home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / ABUSESRC.ZIP / AbuseSrc / abuse / src / game.c < prev    next >
C/C++ Source or Header  |  1997-07-09  |  65KB  |  2,767 lines

  1. #include "game.hpp"
  2. #include "dev.hpp"
  3. #include "id.hpp"
  4. #include "joy.hpp"
  5. #include "timing.hpp"
  6. #include "automap.hpp"
  7. #include "help.hpp"
  8. #include "ability.hpp"
  9. #include "cache.hpp"
  10. #include "loader.hpp"
  11. #include "lisp.hpp"
  12. #include "monoprnt.hpp"
  13. #include "jrand.hpp"
  14. #include "config.hpp"
  15. #include "light.hpp"
  16. #include "scroller.hpp"
  17. #include "dprint.hpp"
  18. #include "nfserver.hpp"
  19. #include "video.hpp"
  20. #include "transp.hpp"
  21. #include "clisp.hpp"
  22. #include "guistat.hpp"
  23. #include "menu.hpp"
  24. #include "gamma.hpp"
  25. #include "lisp_gc.hpp"
  26. #include "demo.hpp"
  27. #include "sbar.hpp"
  28. #include "profile.hpp"
  29. #include "compiled.hpp"
  30. #include "lisp_gc.hpp"
  31. #include "pmenu.hpp"
  32. #include "timing.hpp"
  33. #include "chat.hpp"
  34. #include "demo.hpp"
  35. #include "netcfg.hpp"
  36.  
  37. #ifdef __POWERPC__
  38. #include <profiler.h>  //prof
  39. #endif
  40.  
  41. #include <ctype.h>
  42. #include <setjmp.h>
  43.  
  44. #define SHIFT_RIGHT_DEFAULT 0
  45. #define SHIFT_DOWN_DEFAULT 30
  46.  
  47. class game;
  48. extern crc_manager *net_crcs;
  49. extern void show_verinfo(int argc, char **argv);
  50. game *the_game;
  51. window_manager *eh=NULL;
  52. int dev,shift_down=SHIFT_DOWN_DEFAULT,shift_right=SHIFT_RIGHT_DEFAULT;
  53. double sum_diffs=1,total_diffs=12;
  54. int total_active=0;
  55. long map_xoff=0,map_yoff=0;
  56. long current_vxadd,current_vyadd;
  57. int frame_panic=0,massive_frame_panic=0;
  58. int demo_start=0,idle_ticks=0;
  59. int req_end=0;
  60.  
  61. extern palette *old_pal;
  62. char **start_argv;
  63. int start_argc;
  64. int has_joystick=0;
  65. char req_name[100];
  66.  
  67. int registered=0;
  68. extern uchar chatting_enabled;
  69.  
  70. extern int confirm_quit();
  71.  
  72. #ifdef __POWERPC__
  73. extern char *macify_name(char *s);
  74.  
  75. #include "tcpip.hpp"
  76.  
  77. tcpip_protocol tcpip;
  78.  
  79. #endif
  80.  
  81. FILE *open_FILE(char *filename, char *mode)
  82. {
  83. /*  char *prefix=get_filename_prefix() ? get_filename_prefix() : "",*c;
  84.   
  85.   if (get_save_filename_prefix)
  86.   {
  87.     for (c=mode;*c;c++) 
  88.       if (c=='w' || c=='W') 
  89.       {
  90.       }
  91.   } */
  92.       
  93.   
  94.   char tmp_name[200];
  95.   if (get_filename_prefix() && filename[0] != '/')
  96.     sprintf(tmp_name,"%s%s",get_filename_prefix(),filename);
  97.   else strcpy(tmp_name,filename);
  98. #ifdef __POWERPC__
  99.   macify_name(tmp_name);
  100. #endif
  101.   return fopen(tmp_name,mode);
  102. }
  103.  
  104.  
  105. void handle_no_space()
  106. {
  107.   char *no_space_msg= "\nYou are out of disk space or the game\n"
  108.                       "was unable to write to disk for some reason\n"
  109.                       "The game cannot continue, please check this out\n"
  110.                       "and try again.\n";
  111.   if (eh)
  112.   {
  113.     jwindow *no_space=eh->new_window(0,0,-1,-1,
  114.                      new button(WINDOW_FRAME_LEFT,WINDOW_FRAME_TOP,ID_QUIT_OK,"Quit",
  115.                         new info_field(WINDOW_FRAME_LEFT,WINDOW_FRAME_TOP+eh->font()->height()*2,ID_NULL,
  116.                                   no_space_msg,NULL)),"ERROR");
  117.     event ev;
  118.     do 
  119.     { 
  120.       eh->flush_screen();
  121.       eh->get_event(ev);
  122.     } while (ev.type!=EV_MESSAGE || ev.message.id!=ID_QUIT_OK);
  123.     eh->close_window(no_space);
  124.  
  125.     close_graphics();
  126.     exit(1);
  127.   } else
  128.   {
  129.     fprintf(stderr,"%s\n",no_space_msg);
  130.     exit(0);
  131.   }
  132. }
  133.  
  134. void game::play_sound(int id, int vol, long x, long y)
  135. {
  136.   if (sound_avail&SFX_INITIALIZED)
  137.   {
  138.     if (vol<15) return ;
  139.     if (!player_list) return ;
  140.  
  141.     ulong mdist=0xffffffff;
  142.     view *cd=NULL;
  143.     for (view *f=player_list;f;f=f->next)
  144.     {
  145.       if (f->local_player())
  146.       {
  147.     long cx=abs(f->x_center()-x),cy=abs(f->y_center()-y),d;
  148.     if (cx<cy)
  149.         d=cx+cy-(cx>>1);
  150.     else d=cx+cy-(cy>>1);
  151.  
  152.     if (d<mdist)
  153.     {
  154.       cd=f;
  155.       mdist=d;
  156.     } 
  157.       }
  158.     }  
  159.     if (mdist>500 || !cd) return ;
  160.     if (mdist<100) mdist=0;
  161.     else mdist-=100;
  162.  
  163.     int v=(400-mdist)*sfx_volume/400-(127-vol);
  164.     if (v>0 && (sound_avail&SFX_INITIALIZED))
  165.       cash.sfx(id)->play(v);
  166.   }
  167. }
  168.  
  169. int get_option(char *name)
  170. {
  171.   int i;
  172.   for (i=1;i<start_argc;i++)
  173.     if (!strcmp(start_argv[i],name))
  174.       return i;
  175.   return 0;
  176. }
  177.  
  178.  
  179. void make_screen_size(int w, int h)
  180. {
  181.   for (view *f=player_list;f;f=f->next)
  182.   {
  183.     if (f->local_player())
  184.     {
  185.       if (w>=xres-1) w=xres-2;
  186.       if (h>=yres-1) h=yres-2;
  187.       f->suggest.cx1=(xres+1)/2-w/2;
  188.       f->suggest.cx2=(xres+1)/2+w/2;
  189.       f->suggest.cy1=(yres-31)/2+5-h/2;
  190.       f->suggest.cy2=(yres-51)/2+5+h/2;
  191.       f->suggest.shift_down=f->shift_down;
  192.       f->suggest.shift_right=f->shift_right;
  193.       f->suggest.pan_x=f->pan_x;
  194.       f->suggest.pan_y=f->pan_y;
  195.  
  196.       f->suggest.send_view=1;
  197.     }
  198.   }
  199. }
  200.  
  201. void game::grow_views(int amount)
  202. {
  203.   int undo=0;
  204.   view *f=first_view;
  205.   for (;f;f=f->next)
  206.   {
  207.     if (f->local_player())
  208.     {
  209.       f->suggest.cx1=(f->cx1-amount);
  210.       f->suggest.cy1=f->cy1-amount/2;
  211.       f->suggest.cx2=(f->cx2+amount);
  212.       f->suggest.cy2=f->cy2+amount/2;
  213.       f->suggest.shift_down=f->shift_down;
  214.       f->suggest.shift_right=f->shift_right;
  215.       f->suggest.pan_x=f->pan_x;
  216.       f->suggest.pan_y=f->pan_y;
  217.  
  218.       f->suggest.send_view=1;
  219.     }
  220.   }
  221.  
  222.  
  223.   for (f=first_view;f;f=f->next)  
  224.   {
  225.     if (f->local_player())
  226.     {
  227.       if (f->suggest.cx2-f->suggest.cx1<20 || f->suggest.cy2-f->suggest.cy1<15 || 
  228.     f->suggest.cx1<0 || f->suggest.cy1<0) f->suggest.send_view=0;
  229.       if (f->next && f->next->local_player() && f->suggest.cy2>=f->next->cy1) f->suggest.send_view=0;
  230.     }
  231.   }
  232. }
  233.  
  234. void game::pan(int xv, int yv) 
  235.   first_view->pan_x+=xv; 
  236.   first_view->pan_y+=yv; 
  237. }
  238.  
  239. view *game::view_in(int mousex, int mousey)
  240. {
  241.   for (view *f=first_view;f;f=f->next)
  242.     if (f->drawable() && mousex>=f->cx1 && mousey>=f->cy1 && mousex<=f->cx2 && mousey<=f->cy2)
  243.       return f;
  244.   return NULL;
  245. }
  246.  
  247. int playing_state(int state)
  248.   if (state==RUN_STATE || state==PAUSE_STATE) return 1;
  249.   else return 0;
  250. }
  251.  
  252. void game::ftile_on(int screenx, int screeny, long &x, long &y)
  253. {
  254.   mouse_to_game(screenx,screeny,x,y);
  255.   x/=ftile_width();
  256.   y/=ftile_height();
  257. /*  view *f=view_in(screenx,screeny);
  258.   if (f)
  259.   {
  260.     x=((long)(screenx)-(long)f->cx1+f->xoff())/(long)f_wid;
  261.     y=((long)(screeny)-(long)f->cy1+f->yoff())/(long)f_hi;
  262.   }
  263.   else
  264.   {
  265.     x=-1; 
  266.     y=-1;
  267.   }*/
  268. }
  269.  
  270. void game::btile_on(int screenx, int screeny, long &x, long &y)
  271. {
  272.   view *f=view_in(screenx,screeny);
  273.   if (f)
  274.   {
  275.     x=((long)(screenx)-(long)f->cx1+f->xoff()*bg_xmul/bg_xdiv)/(long)b_wid; 
  276.     y=((long)(screeny)-(long)f->cy1+f->yoff()*bg_ymul/bg_ydiv)/(long)b_hi;
  277.   }
  278.   else
  279.   {
  280.     x=-1; 
  281.     y=-1;
  282.   }
  283. }
  284.  
  285.  
  286. void game::mouse_to_game(long x, long y, long &gamex, long &gamey, view *f)
  287. {
  288.   if (!f)
  289.   {
  290.     f=view_in(x,y);
  291.     if (!f) f=player_list;  // if not in a view use the first on
  292.   }
  293.  
  294.   if (f)
  295.   {
  296.  
  297.       if (dev&MAP_MODE)
  298.       {
  299.     gamex=((x-(long)f->cx1)*ftile_width()/AUTOTILE_WIDTH+map_xoff*ftile_width());
  300.     gamey=((y-(long)f->cy1)*ftile_height()/AUTOTILE_HEIGHT+map_yoff*ftile_height());
  301.       } else
  302.       {
  303.     gamex=(x-(long)f->cx1+f->xoff());
  304.     gamey=(y-(long)f->cy1+f->yoff());
  305.       }
  306.  
  307.   }
  308.  
  309. }
  310.  
  311. void game::game_to_mouse(long gamex, long gamey, view *which, long &x, long &y)
  312. {
  313.   if (dev&MAP_MODE)
  314.   {
  315.     long x1,y1;
  316.     if (dev&EDIT_MODE)
  317.     {
  318.       x1=map_xoff;
  319.       y1=map_yoff;
  320.     } else
  321.     {
  322.       if (which->focus)
  323.       {
  324.     x1=which->focus->x/ftile_width()-(which->cx2-which->cx1)/AUTOTILE_WIDTH/2;
  325.     y1=which->focus->y/ftile_height()-(which->cy2-which->cy1)/AUTOTILE_HEIGHT/2;
  326.       } else x1=y1=0;
  327.     }
  328.     if (x1<0) x1=0;
  329.     if (y1<0) y1=0;
  330.  
  331.     x=gamex*AUTOTILE_WIDTH/ftile_width()-x1*AUTOTILE_WIDTH+which->cx1;
  332.     if (x1>0)
  333.       x-=((which->focus->x*AUTOTILE_WIDTH/ftile_width()) %AUTOTILE_WIDTH);
  334.  
  335.     y=gamey*AUTOTILE_HEIGHT/ftile_height()-y1*AUTOTILE_HEIGHT+which->cy1;
  336.     if (y1>0)
  337.       y-=((which->focus->y*AUTOTILE_HEIGHT/ftile_height()) %AUTOTILE_HEIGHT);
  338.   }
  339.   else
  340.   {
  341.     x=gamex-which->xoff()+which->cx1;
  342.     y=gamey-which->yoff()+which->cy1;
  343.   }
  344. }
  345.  
  346. int window_state(int state)
  347. {
  348.   switch (state)
  349.   {
  350.     case RUN_STATE : 
  351.     case PAUSE_STATE : 
  352.     case JOY_CALB_STATE :
  353.     { return 1; } break;
  354.  
  355.     case INTRO_START_STATE :
  356.     case HELP_STATE : 
  357.     case INTRO_MORPH_STATE :
  358.     case MENU_STATE :
  359.     case SCENE_STATE :
  360.     { return 0; } break;
  361.   }
  362.   return 1;
  363. }
  364.  
  365.  
  366.  
  367. void game::set_state(int new_state) 
  368. {
  369.   int d=0;
  370.   reset_keymap();                             // we think all the keys are up right now
  371.   if (playing_state(new_state) && !playing_state(state))
  372.   {
  373.     if (first_view && first_view!=player_list)
  374.     {
  375.       while (first_view)
  376.       {
  377.     view *tmp=first_view;
  378.     first_view=first_view->next;
  379.     delete tmp;
  380.       }
  381.       first_view=old_view;
  382.       old_view=NULL;
  383.     }
  384.     first_view=player_list;
  385.     d=1;
  386.   } else if (!playing_state(new_state) && (playing_state(state) || state==START_STATE))
  387.   {
  388.     if (player_list)    
  389.     {
  390.       first_view=new view(player_list->focus,NULL,-1);
  391.       first_view->pan_x=player_list->xoff();
  392.       first_view->pan_y=player_list->yoff();
  393.     }
  394.     else    
  395.       first_view=new view(NULL,NULL,0);
  396.     first_view->cx1=(xres+1)/2-155;
  397.     first_view->cy1=(yres+1)/2-95;
  398.     first_view->cx2=(xres+1)/2+155;
  399.     if (total_weapons)
  400.       first_view->cy2=(yres+1)/2+68;
  401.     else
  402.       first_view->cy2=(yres+1)/2+95;
  403.     d=1;
  404.   }
  405.   
  406.  
  407.  
  408.   // switching to/from scene mode cause the screen size to change and the border to change
  409.   // so we need to redraw.
  410.   if (window_state(new_state) && !window_state(state))
  411.     eh->show_windows();
  412.   else if (!window_state(new_state) && window_state(state))
  413.     eh->hide_windows();
  414.  
  415.   int old_state=state;
  416.   state=new_state;
  417.  
  418.   pal->load();    // restore old palette
  419.  
  420.   if (playing_state(state) &&  !(dev&EDIT_MODE))
  421.     eh->set_mouse_shape(cash.img(c_target)->copy(),8,8);
  422.   else
  423.     eh->set_mouse_shape(cash.img(c_normal)->copy(),1,1);
  424.  
  425.   if (old_state==SCENE_STATE && new_state!=SCENE_STATE)
  426.   {
  427.     d=1;
  428.     scene_director.set_abort(0);   // don't skip any more scene stuff
  429.   }
  430.   else if (new_state==SCENE_STATE && old_state!=SCENE_STATE)
  431.     d=1;
  432.   
  433.   if (d)
  434.     draw(state==SCENE_STATE);
  435.  
  436.   dev_cont->set_state(new_state);
  437. }
  438.  
  439. void game::joy_calb(event &ev)
  440. {
  441.   if (joy_win)   // make sure the joy stick calibration window is open
  442.   {
  443.     
  444.     if (ev.type==EV_SPURIOUS)   // spurious means we should update your status
  445.     {
  446.       int b1,b2,b3=0,x,y;
  447.       joy_status(b1,b2,b2,x,y);
  448.       int but=b1|b2|b3;
  449.       if (x>0) x=1; else if (x<0) x=-1;
  450.       if (y>0) y=1; else if (y<0) y=-1;
  451.       if (but) but=1;
  452.       int dx=WINDOW_FRAME_LEFT+20,dy=WINDOW_FRAME_TOP+5;
  453.       image *jim=cash.img(joy_picts[but*9+(y+1)*3+x+1]);
  454.       joy_win->screen->bar(dx,dy,dx+jim->width()+6,dy+jim->height()+6,eh->black());
  455.       jim->put_image(joy_win->screen,dx+3,dy+3);
  456.  
  457.       if (but)
  458.         joy_calibrate();
  459.     } else if (ev.type==EV_MESSAGE && ev.message.id==JOY_OK)
  460.     {
  461.       eh->close_window(joy_win);
  462.       joy_win=NULL;
  463.       set_state(MENU_STATE);
  464.     }        
  465.   }
  466. }
  467.  
  468. void game::menu_select(event &ev)
  469. {
  470.   state=DEV_MOUSE_RELEASE;
  471.   if (top_menu)
  472.   {
  473. /*    eh->push_event(new event(men_mess[((pick_list *)ev.message.data)->get_selection()],NULL));
  474.     eh->close_window(top_menu);
  475.     top_menu=NULL;*/
  476.   }
  477. }
  478.  
  479.  
  480. void game::show_help(char *st)
  481. {
  482.   strcpy(help_text,st);
  483.   help_text_frames=0;  
  484.   refresh=1;
  485. }
  486.  
  487. void game::draw_value(image *screen, int x, int y, int w, int h, int val, int max)
  488. {
  489.   screen->bar(x,y,x+w-1,y+h,eh->dark_color());
  490.   screen->bar(x,y+1,x+w*val/max,y+h-1,eh->bright_color());  
  491. }
  492.  
  493.  
  494. void game::set_level(level *nl)
  495. {
  496.   if (current_level) 
  497.     delete current_level;  
  498.   current_level=nl;
  499. }
  500.  
  501. void game::load_level(char *name)
  502. {
  503.   if (current_level) 
  504.     delete current_level;
  505.  
  506.   bFILE *fp=open_file(name,"rb");
  507.  
  508.   if (fp->open_failure())
  509.   {
  510.     delete fp;
  511.     current_level=new level(100,100,name);
  512.     char msg[100];
  513.     sprintf(msg,symbol_str("no_file"),name);
  514.     show_help(msg);
  515.   }
  516.   else
  517.   {                  
  518.     spec_directory sd(fp);  
  519.  
  520.     spec_entry *e=sd.find("Copyright 1995 Crack dot Com, All Rights reserved"); 
  521.     if (!e)
  522.     { 
  523.       the_game->show_help(symbol_str("missing_c"));
  524.       current_level=new level(100,100,"untitled");
  525.       the_game->need_refresh();
  526.     }
  527.     else 
  528.       current_level=new level(&sd,fp,name);
  529.     delete fp;
  530.   }
  531.   
  532.   base->current_tick=(current_level->tick_counter()&0xff); 
  533.  
  534.   current_level->level_loaded_notify();
  535.   the_game->help_text_frames=0;  
  536.  
  537. }
  538.  
  539. int game::done() 
  540.   return finished || (main_net_cfg && main_net_cfg->restart_state());
  541.  
  542. }
  543.  
  544. void game::end_session()
  545. {
  546.   finished=1;
  547.   if (main_net_cfg)
  548.   {
  549.     delete main_net_cfg;
  550.     main_net_cfg=NULL;
  551.   }
  552. }
  553.  
  554. void game::put_block_fg(int x, int y, trans_image *im)
  555. {
  556.   for (view *f=first_view;f;f=f->next)
  557.   {
  558.     if (f->drawable())
  559.     {
  560.       int xoff=f->xoff(),yoff=f->yoff(),viewx1=f->cx1,viewy1=f->cy1,viewx2=f->cx2,viewy2=f->cy2;
  561.       if (xoff/ftile_width()>x || xoff/ftile_width()+(viewx2-viewx1)/ftile_width()+1<x ||
  562.       yoff/ftile_height()>y || yoff/ftile_height()+(viewy2-viewy1)/ftile_height()+1<y) return;
  563.       short cx1,cy1,cx2,cy2;
  564.       screen->get_clip(cx1,cy1,cx2,cy2);
  565.       screen->set_clip(viewx1,viewy1,viewx2,viewy2);
  566.       im->put_image(screen,(x-xoff/ftile_width())*ftile_width()+viewx1-xoff%ftile_width(),
  567.             (y-yoff/ftile_height())*ftile_height()+viewy1-yoff%ftile_height());
  568.       screen->set_clip(cx1,cy1,cx2,cy2);
  569.     }
  570.   }
  571. }
  572.  
  573. void game::put_block_bg(int x, int y, image *im)
  574. {
  575.   for (view *f=first_view;f;f=f->next)
  576.   {
  577.     if (f->drawable())
  578.     {
  579.       int xoff=f->xoff(),yoff=f->yoff(),viewx1=f->cx1,viewy1=f->cy1,viewx2=f->cx2,viewy2=f->cy2;
  580.       int xo=xoff*bg_xmul/bg_xdiv;
  581.       int yo=yoff*bg_ymul/bg_ydiv;
  582.       
  583.       if (xo/btile_width()>x || xo/btile_width()+(viewx2-viewx1)/btile_width()+1<x ||
  584.       yo/btile_height()>y || yo/btile_height()+(viewy2-viewy1)/btile_height()+1<y) return;
  585.       short cx1,cy1,cx2,cy2;
  586.       screen->get_clip(cx1,cy1,cx2,cy2);
  587.       screen->set_clip(viewx1,viewy1,viewx2,viewy2);
  588.       im->put_image(screen,(x-xo/btile_width())*btile_width()+viewx1-xo%btile_width(),
  589.             (y-yo/btile_height())*btile_height()+viewy1-yo%btile_height(),0);
  590.       screen->set_clip(cx1,cy1,cx2,cy2);
  591.     }
  592.   }
  593. }
  594.  
  595. int need_delay=1;
  596.  
  597. void game::dev_scroll()
  598. {
  599.   need_delay=0;
  600.   if (dev)
  601.   {
  602.     int xmargin,ymargin;
  603.     if (xres>400)
  604.     {
  605.       xmargin=20;
  606.       ymargin=10;
  607.     }
  608.     else 
  609.     {
  610.       xmargin=10;
  611.       ymargin=5;
  612.     }
  613.  
  614.     int xs,ys;
  615.     if (mousex<xmargin &&  dev_cont->ok_to_scroll()) xs=-18;
  616.     else if (mousex>(screen->width()-xmargin) &&  dev_cont->ok_to_scroll()) xs=18;
  617.     else if (eh->key_pressed(JK_LEFT) && !last_input && !dev_cont->need_arrows())
  618.       xs=-18;
  619.     else if (eh->key_pressed(JK_RIGHT) && !last_input && !dev_cont->need_arrows())
  620.       xs=18;
  621.     else xs=0;
  622.          
  623.  
  624.     if (mousey<ymargin && dev_cont->ok_to_scroll()) ys=-18;
  625.     else if (mousey>(screen->height()-ymargin) &&  dev_cont->ok_to_scroll()) ys=18;
  626.     else if (eh->key_pressed(JK_UP) && !last_input)
  627.       ys=-18;
  628.     else if (eh->key_pressed(JK_DOWN) && !last_input)
  629.       ys=18;
  630.     else ys=0;
  631.  
  632.     
  633.     if (xs || ys)
  634.     {
  635.       need_delay=1;
  636.       if (dev&MAP_MODE)
  637.       {
  638.     map_xoff+=xs/2;
  639.     map_yoff+=ys/2;
  640.     if (map_xoff<0) map_xoff=0;
  641.     if (map_yoff<0) map_yoff=0;
  642.       } 
  643.       else
  644.       { 
  645.     for (view *v=first_view;v;v=v->next)
  646.     {
  647.       if (xs>=0 || v->xoff()>0)
  648.         v->pan_x+=xs;
  649.       if (ys>=0 || v->yoff()>0)
  650.         v->pan_y+=ys;
  651.     }
  652.       }
  653.       refresh=1;
  654.     }
  655.   }
  656. }
  657.  
  658. void remap_area(image *screen, int x1, int y1, int x2, int y2, uchar *remap)
  659. {
  660.   uchar *sl=(uchar *)screen->scan_line(y1)+x1;
  661.   int x,y,a=screen->width()-(x2-x1+1);
  662.   uchar c;
  663.   for (y=y1;y<=y2;y++)
  664.   {
  665.     for (x=x1;x<=x2;x++)
  666.     {
  667.       c=*sl;
  668.       *(sl++)=remap[c];
  669.     }
  670.     sl+=a;
  671.   }
  672. }
  673.  
  674. void post_render()
  675. {
  676.   if (DEFINEDP(symbol_function(l_post_render)))
  677.   {
  678.     screen->dirt_off();
  679.     clear_tmp();
  680.     eval_function((lisp_symbol *)l_post_render,NULL);
  681.     clear_tmp();
  682.     screen->dirt_on();
  683.   }
  684. }
  685.   
  686. void game::draw_map(view *v, int interpolate)
  687. {
  688.   foretile *ft;
  689.   backtile *bt;
  690.   int x1,y1,x2,y2,x,y,xo,yo,nxoff,nyoff;
  691.   short cx1,cy1,cx2,cy2;
  692.   screen->get_clip(cx1,cy1,cx2,cy2);
  693.  
  694.   if (!current_level || state==MENU_STATE)
  695.   {
  696.     if (title_screen>=0)
  697.     {
  698.       if (state==SCENE_STATE)
  699.         screen->set_clip(v->cx1,v->cy1,v->cx2,v->cy2);        
  700.       image *tit=cash.img(title_screen);
  701.       tit->put_image(screen,screen->width()/2-tit->width()/2,
  702.                     screen->height()/2-tit->height()/2);
  703.       if (state==SCENE_STATE)
  704.         screen->set_clip(cx1,cy1,cx2,cy2);
  705.       eh->flush_screen();
  706.     }   
  707.     return ;
  708.   }
  709.  
  710.   refresh=0;  
  711.  
  712.  
  713.   // save the dirty rect routines some work by markinging evrything in the 
  714.   // view area dirty alreadt
  715.  
  716.   if (small_render)
  717.     screen->add_dirty(v->cx1,v->cy1,(v->cx2-v->cx1+1)*2+v->cx1,v->cy1+(v->cy2-v->cy1+1)*2);    
  718.   else
  719.     screen->add_dirty(v->cx1,v->cy1,v->cx2,v->cy2);    
  720.  
  721.   if (v->draw_solid!=-1)      // fill the screen and exit..
  722.   {
  723.     int c=v->draw_solid;
  724.     for (int y=v->cy1;y<=v->cy2;y++)
  725.       memset(screen->scan_line(y)+v->cx1,c,v->cx2-v->cx1+1);
  726.     v->draw_solid=-1;
  727.     return ;
  728.   }
  729.  
  730.   long old_cx1,old_cy1,old_cx2,old_cy2;   // if we do a small render, we need to restore these
  731.   image *old_screen=NULL;
  732.   if (small_render && (dev&DRAW_LIGHTS))  // cannot do this if we skip lighting
  733.   {
  734.     old_cx1=v->cx1;
  735.     old_cy1=v->cy1;
  736.     old_cx2=v->cx2;
  737.     old_cy2=v->cy2;
  738.  
  739.     v->cx1=0;
  740.     v->cy1=0;
  741.     v->cx2=small_render->width()-1;
  742.     v->cy2=small_render->height()-1;
  743.  
  744.     old_screen=screen;
  745.     screen=small_render;
  746.   } else
  747.     screen->dirt_off();
  748.  
  749.  
  750.  
  751. //  long max_xoff=(current_level->foreground_width()-1)*ftile_width()-(v->cx2-v->cx1+1);
  752. //  long max_yoff=(current_level->foreground_height()-1)*ftile_height()-(v->cy2-v->cy1+1); 
  753.  
  754.   long xoff,yoff;
  755.   if (interpolate)
  756.   {
  757.     xoff=v->interpolated_xoff();
  758.     yoff=v->interpolated_yoff();
  759.   } else
  760.   {
  761.     xoff=v->xoff();
  762.     yoff=v->yoff();
  763.   }
  764.  
  765. //  if (xoff>max_xoff) xoff=max_xoff;
  766. //  if (yoff>max_yoff) yoff=max_yoff;  
  767.  
  768.   current_vxadd=xoff-v->cx1;
  769.   current_vyadd=yoff-v->cy1;
  770.  
  771.   screen->set_clip(v->cx1,v->cy1,v->cx2,v->cy2);
  772.  
  773.   nxoff=xoff*bg_xmul/bg_xdiv;
  774.   nyoff=yoff*bg_ymul/bg_ydiv;
  775.  
  776. //  long max_bg_xoff=(current_level->background_width())*btile_width()-(v->cx2-v->cx1+1);
  777. //  long max_bg_yoff=(current_level->background_height())*btile_height()-(v->cy2-v->cy1+1);
  778. //  if (nxoff>max_bg_xoff) nxoff=max_xoff;
  779. //  if (nyoff>max_bg_yoff) nyoff=max_yoff;  
  780.   
  781.   
  782.   x1=nxoff/btile_width(); y1=nyoff/btile_height();
  783.   x2=x1+(v->cx2-v->cx1+btile_width())/btile_width();
  784.   y2=y1+(v->cy2-v->cy1+btile_height())/btile_height();
  785.  
  786.  
  787.   xo=v->cx1-nxoff%btile_width();
  788.   yo=v->cy1-nyoff%btile_height();
  789.   
  790.   int xinc,yinc,draw_x,draw_y;
  791.  
  792.  
  793.   if (!(dev & MAP_MODE) && (dev & DRAW_BG_LAYER))
  794.   {
  795.     xinc=btile_width();  
  796.     yinc=btile_height();  
  797.     
  798.     int bh=current_level->background_height(),bw=current_level->background_width();
  799.     ushort *bl;
  800.     for (draw_y=yo,y=y1;y<=y2;y++,draw_y+=yinc)
  801.     {
  802.       if (y>=bh)
  803.         bl=NULL;
  804.       else
  805.         bl=current_level->get_bgline(y)+x1;
  806.  
  807.       for (x=x1,draw_x=xo;x<=x2;x++,draw_x+=xinc)
  808.       {
  809.     if (x<bw && y<bh)
  810.     {
  811.           bt=get_bg(*bl);
  812.       bl++;
  813.     }
  814.     else bt=get_bg(0);
  815.  
  816.         bt->im->put_image(screen,draw_x,draw_y); 
  817. //        if (!(dev & EDIT_MODE) && bt->next)
  818. //      current_level->put_bg(x,y,bt->next);
  819.       }
  820.     }
  821.   }
  822.  
  823. //  if (!(dev&EDIT_MODE))
  824. //    server_check();
  825.  
  826.   uchar rescan=0;  
  827.  
  828.     int fw,fh;
  829.  
  830.     if (dev&MAP_MODE)
  831.     {
  832.       fw=AUTOTILE_WIDTH;
  833.       fh=AUTOTILE_HEIGHT;
  834.       if (dev&EDIT_MODE)
  835.       {
  836.     x1=map_xoff;
  837.     y1=map_yoff;
  838.       } else
  839.       {
  840.     if (v->focus)
  841.     {
  842.       x1=v->focus->x/ftile_width()-(v->cx2-v->cx1)/fw/2;
  843.       y1=v->focus->y/ftile_height()-(v->cy2-v->cy1)/fh/2;
  844.     } else x1=y1=0;
  845.       }
  846.       if (x1>0)
  847.         xo=v->cx1-((v->focus->x*fw/ftile_width()) %fw);
  848.       else xo=v->cx1;
  849.       if (y1>0)
  850.         yo=v->cy1-((v->focus->y*fh/ftile_height()) %fh);
  851.       else yo=v->cy1;
  852.     } else
  853.     {
  854.       fw=ftile_width();
  855.       fh=ftile_height();
  856.       x1=(xoff)/fw; y1=(yoff)/fh;
  857.       xo=v->cx1-xoff%fw;
  858.       yo=v->cy1-yoff%fh;
  859.  
  860.     }
  861.     if (x1<0) x1=0;
  862.     if (y1<0) y1=0;
  863.     
  864.     x2=x1+(v->cx2-v->cx1+fw)/fw;
  865.     y2=y1+(v->cy2-v->cy1+fh)/fh;
  866.     if (x2>=current_level->foreground_width())
  867.       x2=current_level->foreground_width()-1;
  868.     if (y2>=current_level->foreground_height())
  869.       y2=current_level->foreground_height()-1;
  870.  
  871.  
  872.     xinc=fw;
  873.     yinc=fh;
  874.  
  875.   if (dev & DRAW_FG_LAYER)
  876.   {
  877.     short ncx1,ncy1,ncx2,ncy2;
  878.     screen->get_clip(ncx1,ncy1,ncx2,ncy2);
  879.  
  880.     int scr_w=screen->width();
  881.     if (dev&MAP_MODE)
  882.     {
  883.       if (dev&EDIT_MODE)
  884.         screen->clear(eh->bright_color());
  885.       else
  886.         screen->clear(eh->black());
  887.       for (y=y1,draw_y=yo;y<=y2;y++,draw_y+=yinc)
  888.       {
  889.     if (!(draw_y<ncy1 ||draw_y+yinc>=ncy2))
  890.     {
  891.       ushort *cl=current_level->get_fgline(y)+x1;
  892.       uchar *sl1=screen->scan_line(draw_y)+xo;
  893.       for (x=x1,draw_x=xo;x<=x2;x++,cl++,sl1+=xinc,draw_x+=xinc)
  894.       {
  895.         if (!(draw_x<ncx1 || draw_x+xinc>=ncx2))
  896.         {
  897.           int fort_num;
  898. //          if (*cl&0x8000 || (dev&EDIT_MODE))
  899.             fort_num=fgvalue(*cl);
  900. //          else fort_num=0;
  901.  
  902.           uchar *sl2=get_fg(fort_num)->micro_image->scan_line(0);
  903.           uchar *sl3=sl1;
  904.           memcpy(sl3,sl2,AUTOTILE_WIDTH); sl2+=AUTOTILE_WIDTH; sl3+=scr_w;
  905.           memcpy(sl3,sl2,AUTOTILE_WIDTH); sl2+=AUTOTILE_WIDTH; sl3+=scr_w;
  906.           memcpy(sl3,sl2,AUTOTILE_WIDTH);
  907.         }
  908.       }
  909.     }
  910.       }
  911.  
  912.       if (dev&EDIT_MODE)
  913.         current_level->draw_areas(v);
  914.     } else
  915.     {
  916.  
  917.       int fg_h=current_level->foreground_height(),fg_w=current_level->foreground_width();
  918.       
  919.       for (y=y1,draw_y=yo;y<=y2;y++,draw_y+=yinc)
  920.       {
  921.     
  922.     ushort *cl;
  923.     if (y<fg_h)
  924.       cl=current_level->get_fgline(y)+x1;
  925.     else cl=NULL;
  926.     uchar *sl1=draw_y<ncy1 ? 0 : screen->scan_line(draw_y)+xo;
  927.  
  928.     for (x=x1,draw_x=xo;x<=x2;x++,draw_x+=xinc,cl++,sl1+=xinc)
  929.     {
  930.       if (x<fg_w && y<fg_h)
  931.       {
  932.         if (above_tile(*cl))
  933.         rescan=1;
  934.         else
  935.         {
  936.           int fort_num=fgvalue(*cl);      
  937.           if (fort_num!=BLACK)
  938.           {
  939.         if (draw_y<ncy1 || draw_y+yinc>=ncy2 || draw_x<ncx1 || draw_x+xinc>=ncx2)
  940.             get_fg(fort_num)->im->put_image(screen,draw_x,draw_y);
  941.         else
  942.             get_fg(fort_num)->im->put_image_offseted(screen,sl1);
  943.  
  944.         if (!(dev & EDIT_MODE))
  945.             *cl|=0x8000;      // mark as has-been-seen
  946.           }    
  947.         }
  948.       }
  949.     }
  950.       }  
  951.     }
  952. /*        if (dev==0)
  953.           current_level->put_fg(x,y,ft->next);  */       
  954.   }
  955.  
  956. //  if (!(dev&EDIT_MODE))
  957. //    server_check();
  958.  
  959.   long ro=rand_on;
  960.   if (dev & DRAW_PEOPLE_LAYER)
  961.   {
  962.     if (interpolate)
  963.       current_level->interpolate_draw_objects(v);
  964.     else
  965.       current_level->draw_objects(v);
  966.   }
  967.  
  968. //  if (!(dev&EDIT_MODE))
  969. //    server_check();
  970.  
  971.   if (!(dev&MAP_MODE))
  972.   {
  973.  
  974.     draw_panims(v);
  975.  
  976.     int fg_h=current_level->foreground_height(),fg_w=current_level->foreground_width();
  977.  
  978.     if (dev & DRAW_FG_LAYER && rescan)
  979.     {
  980.       for (y=y1,draw_y=yo;y<=y2;y++,draw_y+=yinc)
  981.       {
  982.     ushort *cl=current_level->get_fgline(y)+x1;
  983.     for (x=x1,draw_x=xo;x<=x2;x++,draw_x+=xinc,cl++)
  984.     {
  985.       if (above_tile(*cl))
  986.       {
  987.         int fort_num=fgvalue(*cl);      
  988.         if (fort_num!=BLACK)
  989.         {
  990.           if (dev & DRAW_BG_LAYER)
  991.           get_fg(fort_num)->im->put_image(screen,draw_x,draw_y);
  992.           else
  993.           get_fg(fort_num)->im->put_image_filled(screen,draw_x,draw_y,0);
  994.  
  995.           if (!(dev & EDIT_MODE))
  996.           current_level->mark_seen(x,y);
  997.           else
  998.           {
  999.         screen->line(draw_x,draw_y,draw_x+xinc,draw_y+yinc,eh->bright_color());
  1000.         screen->line(draw_x+xinc,draw_y,draw_x,draw_y+yinc,eh->bright_color());
  1001.           }
  1002.         }    
  1003.       }
  1004.     }
  1005.       }   
  1006.     }
  1007.  
  1008.     
  1009.     if (dev & DRAW_FG_BOUND_LAYER)
  1010.     {
  1011.       int b=eh->bright_color();
  1012.       int fg_h=current_level->foreground_height(),fg_w=current_level->foreground_width();
  1013.  
  1014.       for (y=y1,draw_y=yo;y<=y2;y++,draw_y+=yinc)
  1015.       {
  1016.     ushort *cl;
  1017.     if (y<fg_h)
  1018.       cl=current_level->get_fgline(y)+x1;
  1019.     else cl=NULL;
  1020.     for (x=x1,draw_x=xo;x<=x2;x++,draw_x+=xinc,cl++)
  1021.     {
  1022.       if (x<fg_w && y<fg_h)
  1023.       {
  1024.         int fort_num=fgvalue(*cl);      
  1025.         if (fort_num!=BLACK)
  1026.         {
  1027.           point_list *p=get_fg(fort_num)->points;
  1028.           uchar *d=p->data;    
  1029.           if (p->tot)
  1030.           {
  1031.         for (int i=1;i<p->tot;i++)
  1032.         {
  1033.           d+=2;
  1034.           screen->line(draw_x+*(d-2),draw_y+*(d-1),draw_x+*d,draw_y+*(d+1),b);
  1035.         }
  1036.         screen->line(draw_x+*d,draw_y+*(d-1),draw_x+p->data[0],draw_y+p->data[1],b);
  1037.           }
  1038.         }
  1039.       }
  1040.     }
  1041.       }
  1042.     }
  1043.  
  1044. //    if (!(dev&EDIT_MODE))
  1045. //      server_check();
  1046.  
  1047.     if (dev & DRAW_HELP_LAYER)
  1048.     {
  1049.       if (help_text_frames>=0)
  1050.       {
  1051.     int color;
  1052.     
  1053.     if (help_text_frames<10)
  1054.         color=2;
  1055.     else
  1056.         color=2+(help_text_frames-10);
  1057.     
  1058.     int x1=v->cx1,y1=v->cy1,x2=v->cx2,y2=v->cy1+eh->font()->height()+10;
  1059.  
  1060.     remap_area(screen,x1,y1,x2,y2,white_light+40*256);
  1061.     screen->bar(x1,y1,x2,y1,color);
  1062.     screen->bar(x1,y2,x2,y2,color);
  1063.  
  1064.     eh->font()->put_string(screen,x1+5,y1+5,
  1065.                    help_text,color);
  1066.     if (color>30)
  1067.         help_text_frames=-1;      
  1068.     else help_text_frames++;
  1069.     
  1070.       }    
  1071.     }
  1072.     
  1073.     if (dev_cont)
  1074.     dev_cont->dev_draw(v);  
  1075.     if (cash.in_use())
  1076.     cash.img(vmm_image)->put_image(screen,v->cx1,v->cy2-cash.img(vmm_image)->height()+1);  
  1077.  
  1078.     if (dev&DRAW_LIGHTS)
  1079.     {  
  1080.       if (small_render)
  1081.       {
  1082.     double_light_screen(screen,xoff,yoff,white_light,v->ambient,old_screen,old_cx1,old_cy1);
  1083.  
  1084.     v->cx1=old_cx1;
  1085.     v->cy1=old_cy1;
  1086.     v->cx2=old_cx2;
  1087.     v->cy2=old_cy2;
  1088.     screen=old_screen;
  1089.       } else
  1090.       {      
  1091.     screen->dirt_on();
  1092.     if (xres*yres<=64000)
  1093.           light_screen(screen,xoff,yoff,white_light,v->ambient);
  1094.     else light_screen(screen,xoff,yoff,white_light,63);            // no lighting for hi-rez
  1095.       }
  1096.  
  1097.     } else 
  1098.       screen->dirt_on();
  1099.  
  1100.  
  1101.  
  1102.   }  else
  1103.     screen->dirt_on();
  1104.  
  1105.   rand_on=ro;                // restore random start in case in draw funs moved it
  1106.                                // ... not every machine will draw the same thing
  1107.  
  1108.   post_render();
  1109.  
  1110.   screen->set_clip(cx1,cy1,cx2,cy2);
  1111.     
  1112.  
  1113.  
  1114.  
  1115.   if (playing_state(state))        // draw stuff outside the clipping region
  1116.     v->draw_character_damage();
  1117.  
  1118.   if (profiling())
  1119.     profile_update();
  1120.  
  1121.   sbar.draw_update();
  1122. }
  1123.  
  1124. void game::put_fg(int x, int y, int type)
  1125.   if (current_level->get_fg(x,y)!=type)
  1126.   {
  1127.     current_level->put_fg(x,y,type);
  1128.     for (view *f=first_view;f;f=f->next)
  1129.       if (f->drawable())
  1130.         draw_map(f);    
  1131. /*    put_block_bg(x,y,get_bg(current_level->get_bg(x/ASPECT,y/ASPECT))->im);
  1132.     if (type>BLACK)
  1133.       put_block_fg(x,y,get_fg(type)->im); */
  1134.   }
  1135. }
  1136.  
  1137. void game::put_bg(int x, int y, int type)
  1138. {
  1139.   if (current_level->get_bg(x,y)!=type)
  1140.   {
  1141.     current_level->put_bg(x,y,type);
  1142.     for (view *f=first_view;f;f=f->next)
  1143.       if (f->drawable())
  1144.         draw_map(f);    
  1145. /*    put_block_bg(x,y,get_bg(type)->im);
  1146.     if (current_level->get_fg(x,y)>BLACK) 
  1147.       put_block_fg(x,y,get_fg(current_level->get_fg(x,y))->im);*/
  1148.   }
  1149. }
  1150.  
  1151. int game::in_area(event &ev, int x1, int y1, int x2, int y2)
  1152. {
  1153.   return (last_demo_mx>=x1 && last_demo_mx<=x2 &&
  1154.       last_demo_my>=y1 && last_demo_my<=y2);
  1155. }
  1156.  
  1157. void game::request_level_load(char *name)
  1158. {
  1159.   strcpy(req_name,name);
  1160. }
  1161.  
  1162. extern int start_doubled;
  1163.  
  1164. void fade_in(image *im, int steps)
  1165. {
  1166.   palette *old_pal=pal->copy();
  1167.   int i;
  1168.   if (im)
  1169.   {
  1170.     screen->clear();
  1171.     im->put_image(screen,(xres+1)/2-im->width()/2,(yres+1)/2-im->height()/2);
  1172.   }
  1173.  
  1174.   for (i=0;i<steps;i++)
  1175.   {
  1176.     uchar *sl1=(uchar *)pal->addr();    
  1177.     uchar *sl2=(uchar *)old_pal->addr();    
  1178.     int j;
  1179.     int r,g,b;
  1180.     int v=(i+1)*256/steps;
  1181.     for (j=0;j<256;j++)
  1182.     {
  1183.       *(sl1)=((int)*(sl2))*v/256;  sl1++; sl2++;
  1184.       *(sl1)=((int)*(sl2))*v/256;  sl1++; sl2++;
  1185.       *(sl1)=((int)*(sl2))*v/256;  sl1++; sl2++;
  1186.     }
  1187.     pal->load();
  1188.     eh->flush_screen();
  1189.     milli_wait(25);
  1190.   }
  1191.   delete pal;
  1192.   pal=old_pal;
  1193. }
  1194.  
  1195. void fade_out(int steps)
  1196. {
  1197.   palette *old_pal=pal->copy();
  1198.   int i;
  1199.   for (i=0;i<steps;i++)
  1200.   {
  1201.     uchar *sl1=(uchar *)pal->addr();    
  1202.     uchar *sl2=(uchar *)old_pal->addr();    
  1203.     int j;
  1204.     int r,g,b;
  1205.     int v=(steps-i)*256/steps;
  1206.     for (j=0;j<256;j++)
  1207.     {
  1208.       *(sl1)=((int)*(sl2))*v/256;  sl1++; sl2++;
  1209.       *(sl1)=((int)*(sl2))*v/256;  sl1++; sl2++;
  1210.       *(sl1)=((int)*(sl2))*v/256;  sl1++; sl2++;
  1211.     }
  1212.     pal->load();
  1213.     eh->flush_screen();
  1214.     milli_wait(25);
  1215.   }
  1216.   screen->clear();
  1217.   eh->flush_screen();
  1218.   delete pal;
  1219.   pal=old_pal;
  1220.   
  1221.   pal->load();
  1222. }
  1223.  
  1224. int text_draw(int y, int x1, int y1, int x2, int y2, char *buf, JCFont *font, uchar *cmap, char color);
  1225.  
  1226. void do_title()
  1227. {
  1228.   if (cdc_logo!=-1)
  1229.   {
  1230.     if (sound_avail&MUSIC_INITIALIZED)
  1231.     {
  1232.       if (current_song) { current_song->stop(); delete current_song; }
  1233.       current_song=new song("music/intro.hmi");
  1234.       current_song->play(music_volume);
  1235.     }
  1236.  
  1237.     void *logo_snd=symbol_value(make_find_symbol("LOGO_SND"));
  1238.  
  1239.     if (DEFINEDP(logo_snd) && (sound_avail&SFX_INITIALIZED))
  1240.       cash.sfx(lnumber_value(logo_snd))->play(sfx_volume);
  1241.  
  1242.     image blank(2,2); blank.clear();
  1243.     eh->set_mouse_shape(blank.copy(),0,0);      // don't show mouse
  1244.     fade_in(cash.img(cdc_logo),32);
  1245.     
  1246.     milli_wait(900);
  1247.  
  1248.     void *space_snd=symbol_value(make_find_symbol("SPACE_SND"));
  1249.  
  1250.     fade_out(32);
  1251.     milli_wait(300);
  1252.  
  1253.     int i,abort=0;
  1254.     char *str=lstring_value(eval(make_find_symbol("plot_start")));
  1255.     
  1256.     bFILE *fp=open_file("art/smoke.spe","rb");
  1257.     if (!fp->open_failure())
  1258.     {
  1259.       spec_directory sd(fp);
  1260.       palette *old_pal=pal;
  1261.       pal=new palette(sd.find(SPEC_PALETTE),fp);
  1262.       pal->shift(1);
  1263.  
  1264.       image *gray=new image(sd.find("gray_pict"),fp);
  1265.       image *smoke[5];
  1266.  
  1267.       char nm[20];
  1268.       for (i=0;i<5;i++)
  1269.       {
  1270.     sprintf(nm,"smoke%04d.pcx",i+1);
  1271.     smoke[i]=new image(sd.find(nm),fp);
  1272.       }
  1273.  
  1274.       screen->clear();
  1275.       pal->load();
  1276.  
  1277.       int dx=(xres+1)/2-gray->width()/2,dy=(yres+1)/2-gray->height()/2;
  1278.       gray->put_image(screen,dx,dy);
  1279.       smoke[0]->put_image(screen,dx+24,dy+5);
  1280.  
  1281.       fade_in(NULL,16);
  1282.       uchar cmap[32];
  1283.       for (i=0;i<32;i++)
  1284.         cmap[i]=pal->find_closest(i*256/32,i*256/32,i*256/32);
  1285.  
  1286.       event ev; ev.type=EV_SPURIOUS;
  1287.       time_marker start;
  1288.  
  1289.  
  1290.       for (i=0;i<320 && ev.type!=EV_KEY;i++)
  1291.       {
  1292.     gray->put_image(screen,dx,dy);
  1293.     smoke[i%5]->put_image(screen,dx+24,dy+5);
  1294.     text_draw(205-i,dx+15,dy,dx+320-15,dy+199,str,eh->font(),cmap,eh->bright_color());
  1295.     eh->flush_screen();
  1296.     time_marker now;
  1297.     while (now.diff_time(&start)<0.18) 
  1298.       now.get_time();
  1299.     start.get_time();
  1300.  
  1301.     while (eh->event_waiting() && ev.type!=EV_KEY) eh->get_event(ev);
  1302.     if ((i%5)==0 && DEFINEDP(space_snd) && (sound_avail&SFX_INITIALIZED))
  1303.       cash.sfx(lnumber_value(space_snd))->play(sfx_volume*90/127);
  1304.  
  1305.       }
  1306.  
  1307.       the_game->reset_keymap();
  1308.  
  1309.       fade_out(16);
  1310.  
  1311.       for (i=0;i<5;i++) delete smoke[i];
  1312.       delete gray;
  1313.  
  1314.       delete pal;
  1315.       pal=old_pal;
  1316.     }
  1317.     delete fp;
  1318.  
  1319.     for (i=0;i<100 && !abort;i++)
  1320.     {
  1321.       
  1322.     }
  1323.  
  1324.  
  1325.  
  1326.     if (title_screen>=0)
  1327.       fade_in(cash.img(title_screen),32);
  1328.  
  1329.     eh->set_mouse_shape(cash.img(c_normal)->copy(),1,1);
  1330.   }
  1331. }
  1332.  
  1333. extern int start_edit;
  1334.  
  1335. void game::request_end()
  1336. {
  1337.   req_end=1;
  1338. }
  1339.  
  1340. extern void fast_load_start_recording(char *name);
  1341. extern void fast_load_stop_recording();
  1342. extern void fast_load_start_reloading(char *name);
  1343. extern void fast_load_stop_reloading();
  1344.  
  1345. game::game(int argc, char **argv)
  1346. {
  1347.   int i;
  1348.   req_name[0]=0;
  1349.   bg_xmul=bg_ymul=1;
  1350.   bg_xdiv=bg_ydiv=8;
  1351.   last_input=NULL;
  1352.   current_automap=NULL;
  1353.   current_level=NULL;
  1354.   refresh=1;  
  1355.   the_game=this;  
  1356.   top_menu=joy_win=NULL;
  1357.   old_view=first_view=NULL;
  1358.   nplayers=1;
  1359.  
  1360.   help_text_frames=0;  
  1361.   strcpy(help_text,"");
  1362.  
  1363.   
  1364.   for (i=1;i<argc;i++)
  1365.     if (!strcmp(argv[i],"-no_delay"))
  1366.     {
  1367.       no_delay=1;
  1368.       dprintf("Frame delay off (-nodelay)\n");
  1369.     }
  1370.  
  1371.   
  1372.   image_init();  
  1373.   zoom=15;  
  1374.   no_delay=0;
  1375.  
  1376.   if (get_option("-use_joy"))  
  1377.   {
  1378.     has_joystick=joy_init(argc,argv);
  1379.     dprintf("Joystick : ");
  1380.     if (has_joystick) dprintf("detected\n");
  1381.     else dprintf("not detected\n");
  1382.   }
  1383.   else has_joystick=0;
  1384.  
  1385. //    ProfilerInit(collectDetailed, bestTimeBase, 2000, 200); //prof
  1386.     fast_load_start_recording("fastload.dat");
  1387.   load_data(argc,argv);  
  1388.     fast_load_stop_recording();
  1389. //    ProfilerDump("\pabuse.prof");  //prof    
  1390. //    ProfilerTerm();
  1391.  
  1392.   get_key_bindings();
  1393.  
  1394.   reset_keymap();                   // we think all the keys are up right now
  1395.   finished=0;
  1396.  
  1397.   calc_light_table(pal);
  1398.  
  1399.   if (current_level==NULL && net_start())  // if we joined a net game get level from server
  1400.   {
  1401.     if (!request_server_entry())
  1402.     {
  1403.       exit(0);
  1404.     }
  1405.     net_reload();
  1406. //    load_level(NET_STARTFILE); 
  1407.   }
  1408.  
  1409.  
  1410.   set_mode(19,argc,argv);
  1411.   if (get_option("-2") && (xres<639 || yres<399))
  1412.   {
  1413.     close_graphics();
  1414.     fprintf(stderr,"Resolution must be > 640x400 to use -2 option\n");    
  1415.     exit(0);
  1416.   }
  1417.   pal->load();
  1418.   
  1419.   recalc_local_view_space();   // now that we know what size the screen is...
  1420.  
  1421.   dark_color=get_color(cash.img(window_colors)->pixel(2,0));
  1422.   bright_color=get_color(cash.img(window_colors)->pixel(0,0));
  1423.   med_color=get_color(cash.img(window_colors)->pixel(1,0));
  1424.  
  1425.   morph_dark_color=get_color(cash.img(window_colors)->pixel(2,1));
  1426.   morph_bright_color=get_color(cash.img(window_colors)->pixel(0,1));
  1427.   morph_med_color=get_color(cash.img(window_colors)->pixel(1,1));
  1428.   morph_sel_frame_color=pal->find_closest(255,255,0);
  1429.   light_connection_color=morph_sel_frame_color;
  1430.  
  1431.   if (NILP(symbol_value(l_default_font)))
  1432.   {
  1433.     printf("No font defined, set symbol default-font to an image name\n");
  1434.     exit(0);
  1435.   }
  1436.   int font_pict;
  1437.   if (big_font_pict!=-1)
  1438.   {
  1439.     if (small_font_pict!=-1)
  1440.     {
  1441.       if (xres/(start_doubled ? 2 : 1)>400)
  1442.       {
  1443.     font_pict=big_font_pict;
  1444.       } 
  1445.       else font_pict=small_font_pict;
  1446.     } else font_pict=big_font_pict;
  1447.   } else font_pict=small_font_pict;
  1448.   
  1449.   if (console_font_pict==-1) console_font_pict=font_pict;
  1450.   game_font=new JCFont(cash.img(font_pict));
  1451.  
  1452.   console_font=new JCFont(cash.img(console_font_pict));
  1453.  
  1454.   eh=new window_manager(screen,pal,bright_color,
  1455.                                    med_color,
  1456.                                    dark_color,
  1457.                                    game_font);  
  1458.  
  1459.   delete stat_man;  // move to a graphical status manager
  1460.   gui_status_manager *gstat=new gui_status_manager(eh);
  1461.   gstat->set_window_title("status");
  1462.   stat_man=gstat;
  1463.  
  1464.  
  1465.   chat=new chat_console(eh,console_font,50,6);
  1466.  
  1467.   if (!eh->has_mouse())
  1468.   {
  1469.     close_graphics();
  1470.     image_uninit();
  1471.     printf("No mouse driver detected, please rectify.\n");
  1472.     exit(0);
  1473.   }
  1474.  
  1475.  
  1476.   gamma_correct(pal);
  1477.  
  1478.   if (main_net_cfg==NULL || (main_net_cfg->state!=net_configuration::SERVER &&
  1479.                  main_net_cfg->state!=net_configuration::CLIENT))
  1480.   {
  1481.     if (!start_edit && !net_start())
  1482.       do_title();
  1483.   } else if (main_net_cfg && main_net_cfg->state==net_configuration::SERVER)
  1484.   {
  1485.     the_game->load_level(level_file);
  1486.     start_running=1;
  1487.   }
  1488.     
  1489.  
  1490.   dev|= DRAW_FG_LAYER | DRAW_BG_LAYER | DRAW_PEOPLE_LAYER | DRAW_HELP_LAYER | DRAW_LIGHTS | DRAW_LINKS;
  1491.  
  1492.   if (dev & EDIT_MODE)
  1493.     set_frame_size(0);
  1494. //  do_intro();
  1495.   state=START_STATE;         // first set the state to one that has windows
  1496.  
  1497.  
  1498.   if (start_running)
  1499.     set_state(RUN_STATE);
  1500.   else
  1501.   {
  1502.     screen->clear();  
  1503.     if (title_screen>=0)
  1504.     {
  1505.       image *tit=cash.img(title_screen);
  1506.       tit->put_image(screen,screen->width()/2-tit->width()/2,
  1507.                     screen->height()/2-tit->height()/2);
  1508.     }   
  1509.     set_state(MENU_STATE);   // then go to menu state so windows will turn off
  1510.   }
  1511. }
  1512.  
  1513.  
  1514.  
  1515. time_marker *led_last_time=NULL,*fps_mark_start=NULL;
  1516. double avg_fps=15.0,possible_fps=15.0;
  1517.  
  1518. void game::toggle_delay()
  1519. {
  1520.   no_delay=!no_delay;
  1521.   if (no_delay)
  1522.     show_help(symbol_str("delay_off"));
  1523.   else show_help(symbol_str("delay_on"));
  1524.   avg_fps=possible_fps=15.0;
  1525. }
  1526.  
  1527. void game::show_time()
  1528. {
  1529.   if (first_view && fps_on)
  1530.   {
  1531.     char str[10];
  1532.     sprintf(str,"%d",(long)(avg_fps*10.0));
  1533.     console_font->put_string(screen,first_view->cx1,first_view->cy1,str);
  1534.  
  1535.     sprintf(str,"%d",total_active);
  1536.     console_font->put_string(screen,first_view->cx1,first_view->cy1+10,str);
  1537.   }
  1538. }
  1539.  
  1540. void game::update_screen()
  1541. {
  1542.   if (state==HELP_STATE)
  1543.     draw_help();
  1544.   else if (current_level)
  1545.   {    
  1546.     if (!(dev & EDIT_MODE) || refresh)    
  1547.     {    
  1548.       view *f=first_view;
  1549.       current_level->clear_active_list();
  1550.       for (;f;f=f->next)
  1551.       {
  1552.     if (f->focus)           
  1553.     {
  1554.       int w,h;
  1555.  
  1556.       w=(f->cx2-f->cx1+1);
  1557.       h=(f->cy2-f->cy1+1);
  1558.  
  1559.       total_active+=current_level->add_drawables(f->xoff()-w/4,f->yoff()-h/4,
  1560.                              f->xoff()+w+w/4,f->yoff()+h+h/4);
  1561.  
  1562.     }
  1563.       }
  1564.  
  1565.       for (f=first_view;f;f=f->next)
  1566.       {
  1567.         if (f->drawable())
  1568.     {
  1569.       if (interpolate_draw)
  1570.       {
  1571.             draw_map(f,1);
  1572.         eh->flush_screen();
  1573.       }
  1574.           draw_map(f,0);
  1575.     }
  1576.       }
  1577.       if (current_automap)
  1578.       current_automap->draw();
  1579.     }  
  1580.     if (state==PAUSE_STATE)
  1581.     {
  1582.       for (view *f=first_view;f;f=f->next)
  1583.         cash.img(pause_image)->put_image(screen,(f->cx1+f->cx2)/2-cash.img(pause_image)->width()/2,
  1584.                    f->cy1+5,1);
  1585.     }
  1586.     
  1587.     show_time();
  1588.   }
  1589.  
  1590.   if (state==RUN_STATE && cash.prof_is_on())
  1591.     cash.prof_poll_end();
  1592.  
  1593.   eh->flush_screen();
  1594.  
  1595. }
  1596.  
  1597. void game::do_intro()
  1598. {
  1599.  
  1600. }
  1601.  
  1602. int game::calc_speed()
  1603. {
  1604.   int ret=0;
  1605.   if (fps_mark_start)
  1606.   {
  1607.  
  1608.     time_marker t;
  1609.  
  1610.     // find average fps for last 10 frames
  1611.     double td=t.diff_time(fps_mark_start);
  1612.     if (td<0.001)     // something is rotten in the state of demark
  1613.       td=0.001;
  1614.  
  1615.     avg_fps=avg_fps*9.0/10.0+1.0/(td*10.0);  
  1616.     possible_fps=possible_fps*9.0/10.0+1.0/(td*10.0);  
  1617.  
  1618.     if (avg_fps>14)
  1619.     {
  1620.       if (massive_frame_panic>20)
  1621.         massive_frame_panic=20;
  1622.       else if (massive_frame_panic)
  1623.         massive_frame_panic--;
  1624.     }
  1625.  
  1626.     if (avg_fps>15 && ((dev&EDIT_MODE)==0 || need_delay))
  1627.     {
  1628.       frame_panic=0;
  1629.       long stime=(long)((1/15.0-1.0/possible_fps)*1000.0); 
  1630.       if (stime>0 && !no_delay)
  1631.       {
  1632.         milli_wait(stime);
  1633.     avg_fps-=1.0/(td*10.0);        // subtract out old estimate
  1634.  
  1635.     time_marker t;
  1636.     
  1637.     // find average fps for last 10 frames
  1638.     double td=t.diff_time(fps_mark_start);
  1639.     if (td<0.00001)     // something is rotten in the state of demark
  1640.       td=0.00001;
  1641.  
  1642.     avg_fps+=1.0/(td*10.0);       // add in new estimate
  1643.       }
  1644.     } else if (avg_fps<14)
  1645.     {
  1646.       if (avg_fps<10)
  1647.         massive_frame_panic++;
  1648.       frame_panic++;
  1649.       ret=1;
  1650.     }
  1651.     
  1652.     delete fps_mark_start;    
  1653.   }
  1654.   fps_mark_start=new time_marker;
  1655.   return ret;
  1656. }
  1657.  
  1658. extern int start_edit;
  1659.  
  1660. void single_render();
  1661. void double_render();
  1662.  
  1663. void game::get_input()
  1664. {
  1665.   event ev;  
  1666.   idle_ticks++;
  1667.   while (event_waiting(eh))
  1668.   {
  1669.     get_event(ev,eh);
  1670.  
  1671.     if (ev.type==EV_MOUSE_MOVE) last_input=ev.window;
  1672.     // don't process repeated keys in the main window, it will slow down the game handle such
  1673.     // useless events. However in other windows it might be useful, such as in input windows
  1674.     // where you want to repeatedly scroll down..
  1675.     if (ev.type!=EV_KEY || !key_down(ev.key) || ev.window || (dev&EDIT_MODE))
  1676.     {
  1677.       if (ev.type==EV_KEY)     
  1678.       {
  1679.         set_key_down(ev.key,1);
  1680.     if (playing_state(state))
  1681.     {     
  1682.       if (ev.key<256)
  1683.       {
  1684.         if (chat && chat->chat_event(ev))
  1685.           base->packet.write_byte(SCMD_CHAT_KEYPRESS);
  1686.         else
  1687.           base->packet.write_byte(SCMD_KEYPRESS);
  1688.       }
  1689.       else
  1690.         base->packet.write_byte(SCMD_EXT_KEYPRESS);
  1691.       base->packet.write_byte(client_number());
  1692.       if (ev.key>256)
  1693.         base->packet.write_byte(ev.key-256);
  1694.       else
  1695.         base->packet.write_byte(ev.key);      
  1696.     }
  1697.       }
  1698.       else if (ev.type==EV_KEYRELEASE)
  1699.       {
  1700.         set_key_down(ev.key,0);
  1701.     if (playing_state(state))
  1702.     {     
  1703.       if (ev.key<256)
  1704.         base->packet.write_byte(SCMD_KEYRELEASE);
  1705.       else
  1706.         base->packet.write_byte(SCMD_EXT_KEYRELEASE);
  1707.       base->packet.write_byte(client_number());
  1708.       if (ev.key>255)
  1709.         base->packet.write_byte(ev.key-256);
  1710.       else
  1711.         base->packet.write_byte(ev.key);      
  1712.     }    
  1713.       }
  1714.       
  1715.       if ((dev&EDIT_MODE) || start_edit || ev.type==EV_MESSAGE)
  1716.         dev_cont->handle_event(ev);
  1717.  
  1718.       view *v=first_view;
  1719.       for (;v;v=v->next)
  1720.         if (v->local_player() && v->handle_event(ev))
  1721.       ev.type=EV_SPURIOUS;       // if the event was used by the view, gobble it up
  1722.  
  1723.  
  1724.       if (current_automap)
  1725.         current_automap->handle_event(ev);
  1726.       
  1727.       help_handle_event(ev);    
  1728.       mousex=last_demo_mx;
  1729.       mousey=last_demo_my;
  1730.  
  1731.       if (ev.type==EV_MESSAGE)
  1732.       {
  1733.     switch (ev.message.id)
  1734.     {
  1735.       case CALB_JOY : 
  1736.       { 
  1737.         if (!joy_win)
  1738.         {
  1739.           int wx=WINDOW_FRAME_LEFT,wy=WINDOW_FRAME_TOP;
  1740.           
  1741.           joy_win=eh->new_window(80,50,-1,-1,
  1742.                      new button(wx+70,wy+9,JOY_OK,"OK",
  1743.                      new info_field(wx,wy+30,DEV_NULL,
  1744.                             " Center joystick and\n"
  1745.                             "press the fire button",NULL)),
  1746.  
  1747.                      "Joystick");
  1748.           set_state(JOY_CALB_STATE); 
  1749.         }
  1750.       }
  1751.       case TOP_MENU :
  1752.       { menu_select(ev); } break;
  1753.       case DEV_QUIT :
  1754.       { finished=1; } break;
  1755.  
  1756.     }
  1757.       }        
  1758.       else if (ev.type==EV_CLOSE_WINDOW && ev.window==top_menu)
  1759.       {
  1760.     eh->close_window(top_menu);
  1761.     top_menu=NULL;
  1762.       }
  1763.     
  1764.       switch (state)
  1765.       {
  1766.     case JOY_CALB_STATE :
  1767.     { joy_calb(ev); } break;
  1768.     case INTRO_START_STATE : 
  1769.     { do_intro(); 
  1770.       if (dev & EDIT_MODE)
  1771.         set_state(RUN_STATE);
  1772.       else
  1773.         set_state(MENU_STATE); 
  1774.     } break;     
  1775.     case PAUSE_STATE : if (ev.type==EV_KEY && (ev.key==JK_SPACE || ev.key==JK_ENTER)) 
  1776.                             { set_state(RUN_STATE); } break;
  1777.     case RUN_STATE : 
  1778.     {
  1779.       if (ev.window==NULL)
  1780.       {
  1781.       
  1782.       switch (ev.type)
  1783.       {
  1784.           case EV_KEY : 
  1785.           { switch (ev.key)
  1786.         {
  1787.           case 'm' : 
  1788.           { 
  1789.             if (dev&MAP_MODE) dev-=MAP_MODE;
  1790.             else if ((player_list && player_list->next) || dev&EDIT_MODE) dev|=MAP_MODE;
  1791.  
  1792.             if (!(dev&MAP_MODE))
  1793.             {
  1794.               if (dev_cont->tbw) dev_cont->toggle_toolbar();
  1795.               edit_mode=ID_DMODE_DRAW;
  1796.             }
  1797.             need_refresh();     
  1798.           } break;
  1799.           case 'v' : 
  1800.           { eh->push_event(new event(DO_VOLUME,NULL)); } break;
  1801.                 case 'p' : 
  1802.           { if (!(dev&EDIT_MODE) && (!main_net_cfg || 
  1803.                          (main_net_cfg->state!=net_configuration::SERVER &&
  1804.                           main_net_cfg->state!=net_configuration::CLIENT)))  
  1805.             set_state(PAUSE_STATE); 
  1806.           } break;
  1807.           case 'S' : 
  1808.           if (start_edit)
  1809.           { eh->push_event(new event(ID_LEVEL_SAVE,NULL)); } break;
  1810.           case JK_TAB : 
  1811.           { if (start_edit) toggle_edit_mode(); need_refresh(); } break;
  1812.           case 'c' :          
  1813.           { if (chatting_enabled && (!(dev&EDIT_MODE) && chat))
  1814.               chat->toggle();
  1815.           } break;
  1816.           case '9' : 
  1817.           { dev=dev^PERFORMANCE_TEST_MODE; need_refresh(); } break;
  1818.  
  1819. /*
  1820.           case '=' :
  1821.            case '+' : 
  1822.           { if (!dev_cont->need_plus_minus())
  1823.             { 
  1824.               if (eh->key_pressed(JK_CTRL_L))
  1825.                 grow_views(20);
  1826.               else
  1827.                 grow_views(5); 
  1828.               draw(state==SCENE_STATE);
  1829.             }
  1830.           } break;
  1831.           case JK_F10 : make_screen_size(311,160); break;
  1832.           case '_' :
  1833.           case '-' : 
  1834.           {
  1835.             if (!dev_cont->need_plus_minus())            
  1836.             { 
  1837.               if (eh->key_pressed(JK_CTRL_L))
  1838.                 grow_views(-20);
  1839.               else
  1840.                 grow_views(-5); 
  1841.               draw(state==SCENE_STATE); 
  1842.             } 
  1843.           } break; */
  1844.  
  1845.         }
  1846.             } break;            
  1847.           case EV_RESIZE : 
  1848.           { 
  1849.         view *v;
  1850.         for (v=first_view;v;v=v->next)  // see if any views need to change size
  1851.         {
  1852.           if (v->local_player())
  1853.           {
  1854.             int w=(xres-10)/(small_render ? 2 : 1);
  1855.             int h=(yres-10)/(small_render ? 2 : 1);
  1856.  
  1857.             v->suggest.send_view=1;
  1858.             v->suggest.cx1=5;
  1859.             v->suggest.cx2=5+w;
  1860.             v->suggest.cy1=5;
  1861.             v->suggest.cy2=5+h;
  1862.             v->suggest.pan_x=v->pan_x;
  1863.             v->suggest.pan_y=v->pan_y;
  1864.             v->suggest.shift_down=v->shift_down;
  1865.             v->suggest.shift_right=v->shift_right;
  1866.           }          
  1867.         }
  1868.         draw(); 
  1869.           } break;
  1870.           case EV_REDRAW : screen->add_dirty(ev.redraw.x1,ev.redraw.y1,
  1871.                            ev.redraw.x2,ev.redraw.y2); break;
  1872.           case EV_MESSAGE :        
  1873.                 switch (ev.message.id)
  1874.             {
  1875.               case RAISE_SFX :
  1876.               case LOWER_SFX :
  1877.               case RAISE_MUSIC :
  1878.               case LOWER_MUSIC :
  1879.               if (ev.message.id==RAISE_SFX && sfx_volume!=127) sfx_volume=min(127,sfx_volume+16);
  1880.               if (ev.message.id==LOWER_SFX && sfx_volume!=0) sfx_volume=max(sfx_volume-16,0);
  1881.               if (ev.message.id==RAISE_MUSIC && music_volume!=126) 
  1882.             {            
  1883.               music_volume=min(music_volume+16,127);
  1884.               if (current_song && (sound_avail&MUSIC_INITIALIZED))
  1885.                 current_song->set_volume(music_volume);
  1886.             }
  1887.           
  1888.               if (ev.message.id==LOWER_MUSIC && music_volume!=0) 
  1889.             {            
  1890.               music_volume=max(music_volume-16,0);
  1891.               if (current_song && (sound_avail&MUSIC_INITIALIZED))
  1892.                 current_song->set_volume(music_volume);
  1893.             }            
  1894.           
  1895.               ((button *)ev.message.data)->push();          
  1896. /*            volume_window->inm->redraw();
  1897.             draw_value(volume_window->screen,WINDOW_FRAME_LEFT+2,WINDOW_FRAME_TOP+43,
  1898.                                        (volume_window->x2()-volume_window->x1()-1),8,
  1899.                                        sfx_volume,127);
  1900.             draw_value(volume_window->screen,WINDOW_FRAME_LEFT+2,WINDOW_FRAME_TOP+94,
  1901.                                        (volume_window->x2()-volume_window->x1()-1),8,
  1902.                                        music_volume,127); */
  1903.             break;
  1904.             }
  1905.                   
  1906.         }      
  1907.           }
  1908.         } break;
  1909.       }
  1910.     }
  1911.   }
  1912. }
  1913.  
  1914.  
  1915. void net_send(int force=0)
  1916. {
  1917.   if ( (!(dev&EDIT_MODE)) || force)
  1918.   {
  1919.     if (demo_man.state==demo_manager::PLAYING)
  1920.     {
  1921.       base->input_state=INPUT_PROCESSING;
  1922.     } else
  1923.     {
  1924.       
  1925.  
  1926.  
  1927.       if (!player_list->focus)
  1928.       {
  1929.     dprintf("Players have not been created\ncall create_players");
  1930.     exit(0);
  1931.       }
  1932.  
  1933.  
  1934.       view *p=player_list;
  1935.       for (;p;p=p->next)
  1936.         if (p->local_player())
  1937.       p->get_input();
  1938.  
  1939.  
  1940.       base->packet.write_byte(SCMD_SYNC);
  1941.       base->packet.write_short(make_sync());
  1942.  
  1943.       if (base->join_list)
  1944.       base->packet.write_byte(SCMD_RELOAD);
  1945.  
  1946.       //      printf("save tick %d, pk size=%d, rand_on=%d, sync=%d\n",current_level->tick_counter(),
  1947.       //         base->packet.packet_size(),rand_on,make_sync());
  1948.       send_local_request();
  1949.     }
  1950.   }
  1951. }
  1952.  
  1953. void net_receive()
  1954. {
  1955.   if (!(dev&EDIT_MODE) && current_level)
  1956.   {
  1957.     uchar buf[PACKET_MAX_SIZE+1];
  1958.     int size;
  1959.  
  1960.     if (demo_man.state==demo_manager::PLAYING)
  1961.     { 
  1962.       if (!demo_man.get_packet(buf,size))
  1963.         size=0;
  1964.       base->packet.packet_reset();
  1965.       base->mem_lock=0;
  1966.     } else
  1967.     {
  1968.       size=get_inputs_from_server(buf);
  1969.       if (demo_man.state==demo_manager::RECORDING)
  1970.     demo_man.save_packet(buf,size);
  1971.     }
  1972.  
  1973.     process_packet_commands(buf,size);
  1974.   }
  1975. }
  1976.  
  1977. void game::step()
  1978. {
  1979.   clear_tmp();
  1980.   if (current_level)
  1981.   {
  1982.     current_level->unactivate_all();
  1983.     total_active=0;
  1984.     for (view *f=first_view;f;f=f->next)
  1985.     {
  1986.       if (f->focus)           
  1987.       {
  1988.     f->update_scroll();
  1989.     int w,h;
  1990.  
  1991.     w=(f->cx2-f->cx1+1);
  1992.     h=(f->cy2-f->cy1+1);
  1993.         total_active+=current_level->add_actives(f->xoff()-w/4,f->yoff()-h/4,
  1994.                          f->xoff()+w+w/4,f->yoff()+h+h/4);
  1995.       }
  1996.     }
  1997.   }
  1998.  
  1999.   if (state==RUN_STATE)
  2000.   {    
  2001.     if ((dev&EDIT_MODE) || (main_net_cfg && (main_net_cfg->state==net_configuration::CLIENT ||
  2002.                          main_net_cfg->state==net_configuration::SERVER)))
  2003.       idle_ticks=0;
  2004.  
  2005.     if (demo_man.current_state()==demo_manager::NORMAL && idle_ticks>420 && demo_start)
  2006.     {
  2007.       idle_ticks=0;
  2008.       set_state(MENU_STATE);    
  2009.     }
  2010.     else if (!(dev & EDIT_MODE))               // if edit mode, then don't step anything
  2011.     {
  2012.       if (key_down(JK_ESC))
  2013.       {
  2014.     set_state(MENU_STATE);
  2015.     set_key_down(JK_ESC,0);
  2016.       }
  2017.       ambient_ramp=0;
  2018.       view *v;
  2019.       for (v=first_view;v;v=v->next)
  2020.         v->update_scroll();
  2021.  
  2022.       cash.prof_poll_start();
  2023.       current_level->tick();
  2024.       sbar.step();
  2025.     } else    
  2026.       dev_scroll();  
  2027.   } else if (state==JOY_CALB_STATE)
  2028.   {
  2029.     event ev;
  2030.     joy_calb(ev);
  2031.   } else if (state==MENU_STATE)  
  2032.     main_menu();  
  2033.     
  2034.   if (key_down('x') && (key_down(JK_ALT_L) || key_down(JK_ALT_R)) && confirm_quit()) finished=1;
  2035. }
  2036.  
  2037. extern void *current_demo;
  2038.  
  2039. game::~game()
  2040. {
  2041.   current_demo=NULL;
  2042.   if (first_view==player_list) first_view=NULL;
  2043.   while (player_list)
  2044.   {
  2045.     view *p=player_list;
  2046.     game_object *o=p->focus;
  2047.     player_list=player_list->next;
  2048.     delete p;
  2049.     o->set_controller(NULL);
  2050.     if (current_level && o)
  2051.       current_level->delete_object(o);
  2052.     else delete o;
  2053.   }
  2054.  
  2055.   if (current_level) { delete current_level; current_level=NULL; }
  2056.  
  2057.   if (first_view!=player_list)
  2058.   {
  2059.     while (player_list)
  2060.     {
  2061.       view *p=player_list;
  2062.       player_list=player_list->next;
  2063.       delete p;
  2064.     }
  2065.   }
  2066.  
  2067.   while (first_view)
  2068.   {
  2069.     view *p=first_view;
  2070.     first_view=first_view->next;
  2071.     delete p;
  2072.   }
  2073.  
  2074.   player_list=NULL;  
  2075.  
  2076.   if (old_view)
  2077.   {
  2078.     first_view=old_view;
  2079.     while (first_view)
  2080.     {
  2081.       view *p=first_view;
  2082.       first_view=first_view->next;
  2083.       delete p;
  2084.     }
  2085.   }
  2086.   old_view=NULL;
  2087.  
  2088.   int i=0;
  2089.   for (;i<total_objects;i++)
  2090.   {
  2091.     jfree(object_names[i]);
  2092.     delete figures[i];
  2093.   }
  2094.   free_pframes();
  2095.   if (fps_mark_start) delete fps_mark_start; fps_mark_start=NULL;
  2096.   delete pal;
  2097.   jfree(object_names);
  2098.   jfree(figures);
  2099.  
  2100.   jfree(backtiles);
  2101.   jfree(foretiles);
  2102.   if (total_weapons)
  2103.     jfree(weapon_types);
  2104.  
  2105.   config_cleanup();
  2106.   delete color_table;
  2107.   delete eh;
  2108.   delete game_font;
  2109.   delete big_font;
  2110.   delete console_font;
  2111.   if (total_help_screens)
  2112.     jfree(help_screens);
  2113.     
  2114.   close_graphics();
  2115.   image_uninit();
  2116. }
  2117.  
  2118.  
  2119.  
  2120. void game::draw(int scene_mode)
  2121. {
  2122.   screen->add_dirty(0,0,xres,yres);
  2123.   image *bt=cash.img(border_tile);
  2124.   int tw=bt->width(),th=bt->height(),dx,dy=0;
  2125.   int xt=screen->width()/tw+1,yt=screen->height()/th+1,x,y;
  2126.   screen->clear();
  2127. //  for (y=0;y<yt;y++,dy+=th)
  2128. //    for (x=0,dx=0;x<xt;x++,dx+=tw)
  2129. //      bt->put_image(screen,dx,dy); 
  2130.   int lr=eh->bright_color(),
  2131.       mr=eh->medium_color();
  2132.  
  2133.   if (scene_mode)
  2134.   {
  2135.     char *helpstr="ARROW KEYS CHANGE TEXT SPEED";
  2136.     eh->font()->put_string(screen,screen->width()/2-(eh->font()->width()*strlen(helpstr))/2+1,
  2137.                screen->height()-eh->font()->height()-5+1,helpstr,eh->dark_color());    
  2138.     eh->font()->put_string(screen,screen->width()/2-(eh->font()->width()*strlen(helpstr))/2,
  2139.                screen->height()-eh->font()->height()-5,helpstr,eh->bright_color());    
  2140.   }
  2141. /*  else
  2142.   {
  2143.     char *helpstr="PRESS h FOR HELP";
  2144.     eh->font()->put_string(screen,screen->width()-eh->font()->width()*strlen(helpstr)-5,
  2145.              screen->height()-eh->font()->height()-5,helpstr);
  2146.   }*/
  2147. /*  int dc=cash.img(window_colors)->pixel(0,2);
  2148.   int mc=cash.img(window_colors)->pixel(1,2);
  2149.   int bc=cash.img(window_colors)->pixel(2,2);
  2150.   screen->line(0,0,screen->width()-1,0,dc);
  2151.   screen->line(0,0,0,screen->height()-1,dc);
  2152.   screen->line(0,screen->height()-1,screen->width()-1,screen->height()-1,bc);
  2153.   screen->line(screen->width()-1,0,screen->width()-1,screen->height()-1,bc);*/
  2154.   for (view *f=first_view;f;f=f->next)
  2155.     draw_map(f,0);
  2156.  
  2157.   sbar.redraw(screen);
  2158. }
  2159.  
  2160. int external_print=0;
  2161.  
  2162. void start_sound(int argc, char **argv)
  2163. {
  2164.   sfx_volume=music_volume=127;
  2165.  
  2166.   for (int i=1;i<argc;i++)
  2167.     if (!strcmp(argv[i],"-sfx_volume"))
  2168.     {
  2169.       i++;
  2170.       if (atoi(argv[i])>=0 && atoi(argv[i])<127)
  2171.         sfx_volume=atoi(argv[i]);
  2172.       else printf("Bad sound effects volume level, use 0..127\n");      
  2173.     }
  2174.     else if (!strcmp(argv[i],"-music_volume"))
  2175.     {
  2176.       i++;
  2177.       if (atoi(argv[i])>=0 && atoi(argv[i])<127)
  2178.         music_volume=atoi(argv[i]);
  2179.       else printf("Bad music volume level, use 0..127\n");      
  2180.     }
  2181.  
  2182.   sound_avail=sound_init(argc,argv);
  2183. }
  2184.  
  2185. void game_printer(char *st)
  2186. {
  2187.   if (dev_console && !external_print)
  2188.   {
  2189.     dev_console->put_string(st);
  2190.   }
  2191.   else fprintf(stderr,"%s",st);
  2192. }
  2193.  
  2194.  
  2195. void game_getter(char *st, int max)
  2196. {
  2197.   if (!max) return ;
  2198.   max--;
  2199.   *st=0;
  2200.   if (dev_console && !external_print)
  2201.   {    
  2202.     dev_console->show();
  2203.     int t=0;
  2204.     event ev;
  2205.     do
  2206.     {
  2207.       get_event(ev,eh);
  2208.       if (ev.type==EV_KEY)
  2209.       {
  2210.     if (ev.key==JK_BACKSPACE)
  2211.     {
  2212.       if (t) 
  2213.       {
  2214.         dev_console->printf("%c",ev.key);
  2215.         t--;
  2216.         st--;
  2217.         *st=0;
  2218.         max++;
  2219.       }
  2220.     } else if (ev.key>=' ' && ev.key<='~')
  2221.     {
  2222.       dev_console->printf("%c",ev.key);
  2223.       *st=ev.key;
  2224.       t++;
  2225.       max--;
  2226.       st++;
  2227.       *st=0;
  2228.     }              
  2229.       }
  2230.       eh->flush_screen();
  2231.     } while (ev.type!=EV_KEY || ev.key!=JK_ENTER);    
  2232.     dprintf("\n");
  2233.   }
  2234.   else 
  2235.   {
  2236.     if (fgets(st,max,stdin))
  2237.     {
  2238.       if (*st)
  2239.         st[strlen(st)-1]=0;
  2240.     }
  2241.   }
  2242. }
  2243.  
  2244.  
  2245. void show_startup()
  2246. {
  2247.   show_verinfo(start_argc,start_argv);
  2248. }
  2249.  
  2250. char *get_line(int open_braces)
  2251. {
  2252.   char *line=(char *)jmalloc(1000,"lstring");
  2253.   fgets(line,1000,stdin);
  2254.  
  2255.   char prev=' ';
  2256.   for (char *s=line;*s && (prev!=' ' || *s!=';');s++)
  2257.   {
  2258.     prev=*s;
  2259.     if (*s=='(') open_braces++;
  2260.     else if (*s==')') open_braces--;
  2261.   }
  2262.   if (open_braces<0)    
  2263.     fprintf(stderr,"\nToo many )'s\n");
  2264.   else if (open_braces>0)
  2265.   {
  2266.     char *s2=get_line(open_braces);
  2267.     line=(char *)jrealloc(line,strlen(line)+strlen(s2)+1,"lstring");
  2268.     strcat(line,s2);
  2269.     jfree(s2);    
  2270.   }  
  2271.   return line;
  2272. }
  2273.  
  2274. void check_for_upgrade(int argc, char **argv)
  2275. {
  2276.   for (int i=1;i<argc;i++)
  2277.     if (!strcmp(argv[i],"-upgrade"))
  2278.     {
  2279.       lisp_init(0xf000,0x30000);
  2280.       char *prog="(load \"lisp/upgrade.lsp\")",*cs;
  2281.       cs=prog;
  2282.       if (!eval(compile(cs)))
  2283.     printf("file does not exists : lisp/upgrade.lsp, cannot upgrade\n");
  2284.  
  2285.       exit(0);
  2286.     }        
  2287. }
  2288.  
  2289. void check_for_lisp(int argc, char **argv)
  2290. {
  2291.   for (int i=1;i<argc;i++)
  2292.   {
  2293.     if (!strcmp(argv[i],"-lisp"))
  2294.     {
  2295.       lisp_init(0xf000,0x30000);
  2296.  
  2297. #ifdef __WATCOMC__
  2298.       char *eof_char="CTRL-Z";
  2299. #else
  2300.       char *eof_char="CTRL-D";
  2301. #endif
  2302.       fprintf(stderr,
  2303.               " CLIVE (C) 1995 Jonathan Clark, all rights reserved\n"
  2304.               "   (C LISP interpreter and various extentions)\n"
  2305.               "Type (%s) to exit\n",eof_char);
  2306.  
  2307.       while (!feof(stdin))
  2308.       {
  2309.     fprintf(stderr,"Lisp> ");
  2310.     char *l=get_line(0);
  2311.     char *s=l;
  2312.     while (*s)
  2313.     {
  2314.       void *prog=compile(s);
  2315.       l_user_stack.push(prog);
  2316.       while (*s==' ' || *s=='\t' || *s=='\r' || *s=='\n') s++;
  2317.       lprint(eval(prog));
  2318.       l_user_stack.pop(1);
  2319.     }
  2320.     jfree(l);
  2321.       }      
  2322.  
  2323.       fprintf(stderr,"End of input : bye\n");
  2324.       exit(0);
  2325.     }
  2326.   }
  2327. }
  2328.  
  2329.  
  2330. void music_check()
  2331. {
  2332.   if (sound_avail&MUSIC_INITIALIZED)
  2333.   {
  2334.     if (current_song && !current_song->playing())
  2335.     {
  2336.       current_song->play();
  2337.       dprintf("song finished\n");
  2338.     }
  2339.     if (!current_song)
  2340.     {
  2341.  
  2342.       current_song=new song("music/intro.hmi");
  2343.       current_song->play(music_volume);
  2344.  
  2345. /*      if (DEFINEDP(symbol_function(l_next_song)))  // if user function installed, call it to load up next song
  2346.       {
  2347.     int sp=current_space;
  2348.     current_space=PERM_SPACE;
  2349.     eval_function((lisp_symbol *)l_next_song,NULL);
  2350.     current_space=sp;
  2351.       } */
  2352.     } 
  2353.   }
  2354. }
  2355.  
  2356. void setup(int argc, char **argv);
  2357.  
  2358. void share_end();
  2359. void show_end();
  2360.  
  2361. void show_sell(int abortable);
  2362.  
  2363. extern pmenu *dev_menu;
  2364.  
  2365.  
  2366. extern int jmalloc_max_size;
  2367. extern int jmalloc_min_low_size;
  2368.  
  2369. extern int (*verify_file_fun)(char *,char *);
  2370.  
  2371. int registered_ok(char *filename, char *mode)
  2372. {
  2373.   if (registered) return 1;
  2374.  
  2375.   char name[256],*c;
  2376.   c=name;
  2377.   while (*filename) { *c=*(filename++); *c=toupper(*c); c++; } *c=0;
  2378.   if (strstr(name,"REGISTER"))
  2379.     return 0;
  2380.   else return 1;
  2381. }
  2382.  
  2383. void game_net_init(int argc, char **argv)
  2384. {
  2385.   int nonet=!net_init(argc, argv);
  2386.   if (nonet)
  2387.     dprintf("No network driver, or network driver returned failure\n");
  2388.   else 
  2389.   {
  2390.     set_file_opener(open_nfs_file);
  2391.     if (main_net_cfg && main_net_cfg->state==net_configuration::CLIENT)
  2392.     {
  2393.       if (set_file_server(net_server))
  2394.       start_running=1;
  2395.       else
  2396.       {
  2397.                 dprintf("Unable to attach to server, quiting\n");
  2398.                 exit(0);
  2399.       }
  2400.     } else
  2401.     {
  2402.       int i;
  2403.       for (i=1;i<argc-1;i++)
  2404.       if (!strcmp(argv[i],"-fs"))
  2405.       if (!set_file_server(argv[i+1]))
  2406.       dprintf("could not set defualt file server to %s\n",argv[i+1]);
  2407.     }
  2408.   }    
  2409.  
  2410. }
  2411.  
  2412. #ifdef __POWERPC__
  2413. extern int PixMult;
  2414. #if 1
  2415. char cmdline[256];
  2416. #elif 1
  2417. char cmdline[] = "";
  2418. #elif 1
  2419. char cmdline[] = "abuse -server -a deathmat";
  2420. #else
  2421. char cmdline[] = "abuse -net 193.246.40.9";
  2422. #endif
  2423. char delims[] = " ";
  2424. char *tmp_argv[255];
  2425.  
  2426. void GetArgs(int &argc, char **(&argv))
  2427. {
  2428.     char *s;
  2429.  
  2430.     printf(    "Usage:\n"
  2431.                     "  abuse [-options]\n\n"
  2432.                     "  Options:\n"
  2433.                     "    -server -a deathmat        become a server for deathmatch game\n"
  2434.                     "    -net <dotted ip address>   connect to a server\n\n"
  2435.                     "Options for mac:\n"
  2436.                     "  Hold down <control> for single pixel mode\n"
  2437.                     "  Hold down <option> for edit mode\n"
  2438.                     "  Hold down <left shift> for double size mode\n\n"
  2439.                     "If started with no command line options, networking will attempt\n"
  2440.                     "  to search the local network for servers\n\n"
  2441.     );
  2442.     printf("Enter command line:\n");
  2443.     gets(cmdline);
  2444.     
  2445.     argc = 0;
  2446.     argv = tmp_argv;
  2447.     s = strtok(cmdline, delims);
  2448.     while (s)
  2449.     {
  2450.         argv[argc] = s;
  2451.         argc++;
  2452.         s = strtok(0, delims);
  2453.     }
  2454.     argv[argc] = 0;
  2455. }
  2456.  
  2457. #endif
  2458.  
  2459. int main(int argc, char **argv)
  2460. {
  2461. #ifdef __POWERPC__
  2462.     GetArgs(argc,argv);
  2463. #endif
  2464.  
  2465.   start_argc=argc;
  2466.   start_argv=argv;
  2467.   
  2468.   { for (int i=0;i<argc;i++)
  2469.     {
  2470.       if (!strcmp(argv[i],"-cprint"))
  2471.         external_print=1;
  2472.       if (!strcmp(argv[i],"-min_low"))
  2473.       {
  2474.                 i++;
  2475.         jmalloc_min_low_size=atoi(argv[i]);
  2476.       }
  2477.     }
  2478.   }
  2479.  
  2480. //  jmalloc_max_size=0x150000;
  2481.   jmalloc_init(0x150000); 
  2482. //  jmalloc_init(100000); 
  2483.  
  2484. #ifdef __POWERPC__
  2485.     unsigned char km[16];
  2486.     
  2487.     fprintf(stderr,"Mac Options: ");
  2488.     xres = 320; yres = 200;
  2489.     GetKeys((unsigned long*)&km);
  2490.     if ((km[ 0x3a >>3] >> (0x3a & 7)) &1 != 0)
  2491.     {
  2492.         dev|=EDIT_MODE;    
  2493.         start_edit=1;
  2494.         start_running=1;
  2495.         disable_autolight=1;
  2496.         fprintf(stderr,"Edit Mode...");
  2497.     }
  2498.     if ((km[ 0x3b >>3] >> (0x3b & 7)) &1 != 0)
  2499.     {
  2500.         PixMult = 1;
  2501.         fprintf(stderr,"Single Pixel...");
  2502.     }
  2503.     else
  2504.     {
  2505.         PixMult = 2;
  2506.         fprintf(stderr,"Double Pixel...");
  2507.     }
  2508.     if ((km[ 0x38 >>3] >> (0x38 & 7)) &1 != 0)
  2509.     {
  2510.         xres *= 2;  yres *= 2;
  2511.         fprintf(stderr,"Double Size...");
  2512.     }
  2513.     fprintf(stderr,"\n");
  2514.     
  2515.     if (tcpip.installed())
  2516.         fprintf(stderr, "Using %s\n", tcpip.name());
  2517. #endif
  2518.  
  2519.   set_dprinter(game_printer);
  2520.   set_dgetter(game_getter);
  2521.   set_no_space_handler(handle_no_space);
  2522.  
  2523.   setup(argc,argv);
  2524.  
  2525.   show_startup();
  2526.  
  2527.   start_sound(argc,argv);
  2528.  
  2529.   stat_man=new text_status_manager();
  2530.   if (!get_option("-no_timer"))
  2531.   {
  2532.     timer_init();
  2533.   }
  2534.  
  2535.   if (getenv("ABUSE_PATH"))       // look to see if we are supposed to fetch the data elsewhere
  2536.     set_filename_prefix(getenv("ABUSE_PATH"));   
  2537.  
  2538.   if (getenv("ABUSE_SAVE_PATH"))       // look to see if we are supposed to fetch the data elsewhere
  2539.     set_save_filename_prefix(getenv("ABUSE_SAVE_PATH"));   
  2540.  
  2541.   if (!get_option("-share"))
  2542.   {
  2543.     jFILE *fp=new jFILE("register/micron.vcd","rb");
  2544.     if (!fp->open_failure())
  2545.     {
  2546.       spec_directory sd(fp);
  2547.       if (sd.find("Copyright (C) 1995 Crack dot Com, All Rights reserved"))
  2548.         registered=1;
  2549.     }
  2550.     delete fp;
  2551.   }
  2552.  
  2553.   verify_file_fun=registered_ok;
  2554.  
  2555.  
  2556.  
  2557.   jrand_init();
  2558.   jrand();  // so compiler doesn't complain
  2559.  
  2560.  
  2561.   set_spec_main_file("abuse.spe");
  2562.  
  2563.   check_for_lisp(argc,argv);
  2564.   check_for_upgrade(argc,argv);
  2565.  
  2566.   do
  2567.   {
  2568.     if (main_net_cfg) 
  2569.     {
  2570.       if (!main_net_cfg->notify_reset())
  2571.       {
  2572.     if (!get_option("-no_timer"))
  2573.       timer_uninit();
  2574.     sound_uninit();
  2575.     exit(0);
  2576.       }
  2577.     }
  2578.  
  2579.     game_net_init(argc,argv);
  2580.     lisp_init(0x16000,0x94000);
  2581.     //  lisp_init(0x100000,0x10000);
  2582.  
  2583.     dev_init(argc,argv);
  2584.  
  2585.  
  2586.     game *g=new game(argc,argv);
  2587.  
  2588.  
  2589.  
  2590.  
  2591.     dev_cont=new dev_controll();
  2592.     dev_cont->load_stuff();
  2593.  
  2594.  
  2595.  
  2596.     g->get_input();      // prime the net
  2597.  
  2598.     int xx;
  2599.     for (xx=1;xx<argc;xx++)
  2600.       if (!strcmp(argv[xx],"-server"))
  2601.       {
  2602.                 xx++;
  2603.                 if (!become_server(argv[xx]))
  2604.                 {      
  2605.                   dprintf("unable to become a server\n");
  2606.                   exit(0);
  2607.                 }
  2608.                 xx=argc+1;
  2609.       }
  2610.  
  2611.     if (main_net_cfg) 
  2612.       wait_min_players();
  2613.  
  2614.     net_send(1);
  2615.     if (net_start())
  2616.     {
  2617.       g->step();                        // process all the objects in the 
  2618.       g->calc_speed();
  2619.       g->update_screen();               // redraw the screen with any changes
  2620.     }
  2621.  
  2622.     while (!g->done())
  2623.     {   
  2624.       music_check();
  2625.  
  2626.       if (req_end)
  2627.       {
  2628.                 delete current_level;
  2629.                 current_level=NULL;
  2630.                 
  2631.                 if (!registered)
  2632.                 share_end();
  2633.                 else show_end();
  2634.             
  2635.                 the_game->set_state(MENU_STATE);
  2636.                 req_end=0;
  2637.       }
  2638.       
  2639.  
  2640.       if (demo_man.current_state()==demo_manager::NORMAL)
  2641.       {
  2642.                 net_receive();
  2643.       }
  2644.  
  2645.       if (req_name[0])            // see if a request for a level load was made during the last tick
  2646.       {
  2647.                 g->load_level(req_name);
  2648.                 req_name[0]=0;
  2649.                 g->draw(g->state==SCENE_STATE);
  2650.       }
  2651.  
  2652.       //    if (demo_man.current_state()!=demo_manager::PLAYING)
  2653.       g->get_input();
  2654.       
  2655.       if (demo_man.current_state()==demo_manager::NORMAL)
  2656.       net_send();
  2657.       else demo_man.do_inputs();
  2658.  
  2659.       service_net_request();
  2660.  
  2661.       g->step();                        // process all the objects in the 
  2662.  
  2663.       server_check();
  2664.  
  2665.       g->calc_speed();
  2666.       if (!req_name[0])                // see if a request for a level load was made during the last tick
  2667.         g->update_screen();               // redraw the screen with any changes
  2668.  
  2669.  
  2670.     }
  2671.  
  2672.     net_uninit();
  2673.  
  2674.     if (net_crcs)
  2675.     {
  2676.       net_crcs->clean_up();
  2677.       delete net_crcs;
  2678.       net_crcs=NULL;
  2679.     }
  2680.  
  2681.     delete chat;
  2682.  
  2683.     if (!registered)
  2684.     show_sell(0);
  2685.     else milli_wait(500);
  2686.  
  2687.  
  2688.     if (small_render) { delete small_render; small_render=NULL; }
  2689.  
  2690.     if (current_song) 
  2691.     { current_song->stop();
  2692.       delete current_song; 
  2693.       current_song=NULL; 
  2694.     }
  2695.  
  2696.  
  2697.     cash.empty();
  2698.  
  2699.  
  2700.     if (dev_console)
  2701.     {
  2702.       delete dev_console;
  2703.       dev_console=NULL;
  2704.     }
  2705.  
  2706.     if (dev_menu)
  2707.     {
  2708.       delete dev_menu;
  2709.       dev_menu=NULL;
  2710.     }
  2711.  
  2712.     delete g;
  2713.     if (old_pal) delete old_pal; old_pal=NULL;
  2714.     compiled_uninit();
  2715.     delete_all_lights();
  2716.     jfree(white_light_initial);
  2717.  
  2718.     for (int i=0;i<TTINTS;i++) jfree(tints[i]);
  2719.  
  2720.  
  2721.     dev_cleanup();
  2722.     delete dev_cont; dev_cont=NULL;
  2723.     delete stat_man; 
  2724.     stat_man=new text_status_manager();
  2725.  
  2726.     if (!(main_net_cfg && main_net_cfg->restart_state()))
  2727.     {
  2728.       void *end_msg=make_find_symbol("end_msg");
  2729.       if (DEFINEDP(symbol_value(end_msg)))
  2730.       printf("%s\n",lstring_value(symbol_value(end_msg)));
  2731.     }
  2732.  
  2733.     lisp_uninit();
  2734.  
  2735.     base->packet.packet_reset();
  2736.     mem_report("end.mem");
  2737.   } while (main_net_cfg && main_net_cfg->restart_state());
  2738.  
  2739.  
  2740.   delete stat_man;
  2741.  
  2742.   if (main_net_cfg) { delete main_net_cfg; main_net_cfg=NULL; }
  2743.   set_filename_prefix(NULL);  // dealloc this mem if there was any
  2744.   set_save_filename_prefix(NULL);
  2745.  
  2746.   if (!get_option("-no_timer"))
  2747.     timer_uninit();
  2748.  
  2749.   mem_report("end.mem");
  2750.  
  2751. //  jmalloc_uninit();
  2752.   l_user_stack.clean_up();
  2753.   l_ptr_stack.clean_up();
  2754.  
  2755.   sound_uninit();
  2756.  
  2757.   exit(0);
  2758.  
  2759.   return 0;  
  2760. }
  2761.  
  2762.  
  2763.